@almadar/ui 5.64.0 → 5.65.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 +84 -22
- package/dist/avl/index.js +84 -22
- package/dist/components/game/molecules/IsometricCanvas.d.ts +4 -1
- package/dist/components/game/molecules/index.d.ts +1 -0
- package/dist/components/game/organisms/HexStrategyBoard.d.ts +37 -0
- package/dist/components/game/organisms/index.d.ts +2 -0
- package/dist/components/game/organisms/utils/isometric.d.ts +20 -7
- package/dist/components/index.cjs +86 -22
- package/dist/components/index.js +86 -23
- package/dist/providers/index.cjs +84 -22
- package/dist/providers/index.js +84 -22
- package/dist/runtime/index.cjs +84 -22
- package/dist/runtime/index.js +84 -22
- package/package.json +1 -1
package/dist/avl/index.cjs
CHANGED
|
@@ -14723,16 +14723,26 @@ var init_useUnitSpriteAtlas = __esm({
|
|
|
14723
14723
|
});
|
|
14724
14724
|
|
|
14725
14725
|
// components/game/organisms/utils/isometric.ts
|
|
14726
|
-
function isoToScreen(tileX, tileY, scale, baseOffsetX) {
|
|
14726
|
+
function isoToScreen(tileX, tileY, scale, baseOffsetX, layout = "isometric") {
|
|
14727
14727
|
const scaledTileWidth = TILE_WIDTH * scale;
|
|
14728
14728
|
const scaledFloorHeight = FLOOR_HEIGHT * scale;
|
|
14729
|
+
if (layout === "hex") {
|
|
14730
|
+
const screenX2 = tileX * scaledTileWidth + (tileY & 1) * (scaledTileWidth / 2) + baseOffsetX;
|
|
14731
|
+
const screenY2 = tileY * (scaledFloorHeight * 0.75);
|
|
14732
|
+
return { x: screenX2, y: screenY2 };
|
|
14733
|
+
}
|
|
14729
14734
|
const screenX = (tileX - tileY) * (scaledTileWidth / 2) + baseOffsetX;
|
|
14730
14735
|
const screenY = (tileX + tileY) * (scaledFloorHeight / 2);
|
|
14731
14736
|
return { x: screenX, y: screenY };
|
|
14732
14737
|
}
|
|
14733
|
-
function screenToIso(screenX, screenY, scale, baseOffsetX) {
|
|
14738
|
+
function screenToIso(screenX, screenY, scale, baseOffsetX, layout = "isometric") {
|
|
14734
14739
|
const scaledTileWidth = TILE_WIDTH * scale;
|
|
14735
14740
|
const scaledFloorHeight = FLOOR_HEIGHT * scale;
|
|
14741
|
+
if (layout === "hex") {
|
|
14742
|
+
const row = Math.round(screenY / (scaledFloorHeight * 0.75));
|
|
14743
|
+
const col = Math.round((screenX - (row & 1) * (scaledTileWidth / 2) - baseOffsetX) / scaledTileWidth);
|
|
14744
|
+
return { x: col, y: row };
|
|
14745
|
+
}
|
|
14736
14746
|
const adjustedX = screenX - baseOffsetX;
|
|
14737
14747
|
const tileX = (adjustedX / (scaledTileWidth / 2) + screenY / (scaledFloorHeight / 2)) / 2;
|
|
14738
14748
|
const tileY = (screenY / (scaledFloorHeight / 2) - adjustedX / (scaledTileWidth / 2)) / 2;
|
|
@@ -14782,6 +14792,7 @@ function IsometricCanvas({
|
|
|
14782
14792
|
tileHoverEvent,
|
|
14783
14793
|
tileLeaveEvent,
|
|
14784
14794
|
// Rendering options
|
|
14795
|
+
tileLayout = "isometric",
|
|
14785
14796
|
scale = 0.4,
|
|
14786
14797
|
debug: debug2 = false,
|
|
14787
14798
|
backgroundImage = "",
|
|
@@ -14851,13 +14862,17 @@ function IsometricCanvas({
|
|
|
14851
14862
|
);
|
|
14852
14863
|
const sortedTiles = React93.useMemo(() => {
|
|
14853
14864
|
const tiles = [...tilesProp];
|
|
14854
|
-
|
|
14855
|
-
|
|
14856
|
-
|
|
14857
|
-
|
|
14858
|
-
|
|
14865
|
+
if (tileLayout === "hex") {
|
|
14866
|
+
tiles.sort((a, b) => a.y !== b.y ? a.y - b.y : a.x - b.x);
|
|
14867
|
+
} else {
|
|
14868
|
+
tiles.sort((a, b) => {
|
|
14869
|
+
const depthA = a.x + a.y;
|
|
14870
|
+
const depthB = b.x + b.y;
|
|
14871
|
+
return depthA !== depthB ? depthA - depthB : a.y - b.y;
|
|
14872
|
+
});
|
|
14873
|
+
}
|
|
14859
14874
|
return tiles;
|
|
14860
|
-
}, [tilesProp]);
|
|
14875
|
+
}, [tilesProp, tileLayout]);
|
|
14861
14876
|
const gridWidth = React93.useMemo(() => {
|
|
14862
14877
|
if (sortedTiles.length === 0) return 0;
|
|
14863
14878
|
return Math.max(...sortedTiles.map((t2) => t2.x)) + 1;
|
|
@@ -14971,7 +14986,7 @@ function IsometricCanvas({
|
|
|
14971
14986
|
miniCanvas.width = mW;
|
|
14972
14987
|
miniCanvas.height = mH;
|
|
14973
14988
|
mCtx.clearRect(0, 0, mW, mH);
|
|
14974
|
-
const allScreenPos = sortedTiles.map((t2) => isoToScreen(t2.x, t2.y, scale, baseOffsetX));
|
|
14989
|
+
const allScreenPos = sortedTiles.map((t2) => isoToScreen(t2.x, t2.y, scale, baseOffsetX, tileLayout));
|
|
14975
14990
|
const minX = Math.min(...allScreenPos.map((p2) => p2.x));
|
|
14976
14991
|
const maxX = Math.max(...allScreenPos.map((p2) => p2.x + scaledTileWidth));
|
|
14977
14992
|
const minY = Math.min(...allScreenPos.map((p2) => p2.y));
|
|
@@ -14982,7 +14997,7 @@ function IsometricCanvas({
|
|
|
14982
14997
|
const offsetMx = (mW - worldW * scaleM) / 2;
|
|
14983
14998
|
const offsetMy = (mH - worldH * scaleM) / 2;
|
|
14984
14999
|
for (const tile of sortedTiles) {
|
|
14985
|
-
const pos = isoToScreen(tile.x, tile.y, scale, baseOffsetX);
|
|
15000
|
+
const pos = isoToScreen(tile.x, tile.y, scale, baseOffsetX, tileLayout);
|
|
14986
15001
|
const mx = (pos.x - minX) * scaleM + offsetMx;
|
|
14987
15002
|
const my = (pos.y - minY) * scaleM + offsetMy;
|
|
14988
15003
|
const mTileW = scaledTileWidth * scaleM;
|
|
@@ -14998,7 +15013,7 @@ function IsometricCanvas({
|
|
|
14998
15013
|
}
|
|
14999
15014
|
for (const unit of units) {
|
|
15000
15015
|
if (!unit.position) continue;
|
|
15001
|
-
const pos = isoToScreen(unit.position.x, unit.position.y, scale, baseOffsetX);
|
|
15016
|
+
const pos = isoToScreen(unit.position.x, unit.position.y, scale, baseOffsetX, tileLayout);
|
|
15002
15017
|
const mx = (pos.x + scaledTileWidth / 2 - minX) * scaleM + offsetMx;
|
|
15003
15018
|
const my = (pos.y + scaledTileHeight / 2 - minY) * scaleM + offsetMy;
|
|
15004
15019
|
mCtx.fillStyle = unit.team === "player" ? "#60a5fa" : unit.team === "enemy" ? "#f87171" : "#9ca3af";
|
|
@@ -15014,7 +15029,7 @@ function IsometricCanvas({
|
|
|
15014
15029
|
mCtx.strokeStyle = "rgba(255, 255, 255, 0.8)";
|
|
15015
15030
|
mCtx.lineWidth = 1;
|
|
15016
15031
|
mCtx.strokeRect(vLeft, vTop, vW, vH);
|
|
15017
|
-
}, [showMinimap, sortedTiles, units, scale, baseOffsetX, scaledTileWidth, scaledTileHeight, scaledFloorHeight, viewportSize, cameraRef]);
|
|
15032
|
+
}, [showMinimap, sortedTiles, units, tileLayout, scale, baseOffsetX, scaledTileWidth, scaledTileHeight, scaledFloorHeight, viewportSize, cameraRef]);
|
|
15018
15033
|
const draw = React93.useCallback((animTime) => {
|
|
15019
15034
|
const canvas = canvasRef.current;
|
|
15020
15035
|
if (!canvas) return;
|
|
@@ -15054,7 +15069,7 @@ function IsometricCanvas({
|
|
|
15054
15069
|
const visTop = cam.y - viewportSize.height / cam.zoom;
|
|
15055
15070
|
const visBottom = cam.y + viewportSize.height * 2 / cam.zoom;
|
|
15056
15071
|
for (const tile of sortedTiles) {
|
|
15057
|
-
const pos = isoToScreen(tile.x, tile.y, scale, baseOffsetX);
|
|
15072
|
+
const pos = isoToScreen(tile.x, tile.y, scale, baseOffsetX, tileLayout);
|
|
15058
15073
|
if (pos.x + scaledTileWidth < visLeft || pos.x > visRight || pos.y + scaledTileHeight < visTop || pos.y > visBottom) {
|
|
15059
15074
|
continue;
|
|
15060
15075
|
}
|
|
@@ -15134,12 +15149,13 @@ function IsometricCanvas({
|
|
|
15134
15149
|
}
|
|
15135
15150
|
}
|
|
15136
15151
|
const sortedFeatures = [...features].sort((a, b) => {
|
|
15152
|
+
if (tileLayout === "hex") return a.y !== b.y ? a.y - b.y : a.x - b.x;
|
|
15137
15153
|
const depthA = a.x + a.y;
|
|
15138
15154
|
const depthB = b.x + b.y;
|
|
15139
15155
|
return depthA !== depthB ? depthA - depthB : a.y - b.y;
|
|
15140
15156
|
});
|
|
15141
15157
|
for (const feature of sortedFeatures) {
|
|
15142
|
-
const pos = isoToScreen(feature.x, feature.y, scale, baseOffsetX);
|
|
15158
|
+
const pos = isoToScreen(feature.x, feature.y, scale, baseOffsetX, tileLayout);
|
|
15143
15159
|
if (pos.x + scaledTileWidth < visLeft || pos.x > visRight || pos.y + scaledTileHeight < visTop || pos.y > visBottom) {
|
|
15144
15160
|
continue;
|
|
15145
15161
|
}
|
|
@@ -15174,12 +15190,13 @@ function IsometricCanvas({
|
|
|
15174
15190
|
}
|
|
15175
15191
|
const unitsWithPosition = units.filter((u) => !!u.position);
|
|
15176
15192
|
const sortedUnits = [...unitsWithPosition].sort((a, b) => {
|
|
15193
|
+
if (tileLayout === "hex") return a.position.y !== b.position.y ? a.position.y - b.position.y : a.position.x - b.position.x;
|
|
15177
15194
|
const depthA = a.position.x + a.position.y;
|
|
15178
15195
|
const depthB = b.position.x + b.position.y;
|
|
15179
15196
|
return depthA !== depthB ? depthA - depthB : a.position.y - b.position.y;
|
|
15180
15197
|
});
|
|
15181
15198
|
for (const unit of sortedUnits) {
|
|
15182
|
-
const pos = isoToScreen(unit.position.x, unit.position.y, scale, baseOffsetX);
|
|
15199
|
+
const pos = isoToScreen(unit.position.x, unit.position.y, scale, baseOffsetX, tileLayout);
|
|
15183
15200
|
if (pos.x + scaledTileWidth < visLeft || pos.x > visRight || pos.y + scaledTileHeight < visTop || pos.y > visBottom) {
|
|
15184
15201
|
continue;
|
|
15185
15202
|
}
|
|
@@ -15199,7 +15216,7 @@ function IsometricCanvas({
|
|
|
15199
15216
|
drawH = maxUnitW / ar;
|
|
15200
15217
|
}
|
|
15201
15218
|
if (unit.previousPosition && (unit.previousPosition.x !== unit.position.x || unit.previousPosition.y !== unit.position.y)) {
|
|
15202
|
-
const ghostPos = isoToScreen(unit.previousPosition.x, unit.previousPosition.y, scale, baseOffsetX);
|
|
15219
|
+
const ghostPos = isoToScreen(unit.previousPosition.x, unit.previousPosition.y, scale, baseOffsetX, tileLayout);
|
|
15203
15220
|
const ghostCenterX = ghostPos.x + scaledTileWidth / 2;
|
|
15204
15221
|
const ghostGroundY = ghostPos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
|
|
15205
15222
|
ctx.save();
|
|
@@ -15328,6 +15345,7 @@ function IsometricCanvas({
|
|
|
15328
15345
|
units,
|
|
15329
15346
|
features,
|
|
15330
15347
|
selectedUnitId,
|
|
15348
|
+
tileLayout,
|
|
15331
15349
|
scale,
|
|
15332
15350
|
debug2,
|
|
15333
15351
|
resolveTerrainSpriteUrl,
|
|
@@ -15356,14 +15374,14 @@ function IsometricCanvas({
|
|
|
15356
15374
|
if (!selectedUnitId) return;
|
|
15357
15375
|
const unit = units.find((u) => u.id === selectedUnitId);
|
|
15358
15376
|
if (!unit?.position) return;
|
|
15359
|
-
const pos = isoToScreen(unit.position.x, unit.position.y, scale, baseOffsetX);
|
|
15377
|
+
const pos = isoToScreen(unit.position.x, unit.position.y, scale, baseOffsetX, tileLayout);
|
|
15360
15378
|
const centerX = pos.x + scaledTileWidth / 2;
|
|
15361
15379
|
const centerY = pos.y + scaledDiamondTopY + scaledFloorHeight / 2;
|
|
15362
15380
|
targetCameraRef.current = {
|
|
15363
15381
|
x: centerX - viewportSize.width / 2,
|
|
15364
15382
|
y: centerY - viewportSize.height / 2
|
|
15365
15383
|
};
|
|
15366
|
-
}, [selectedUnitId, units, scale, baseOffsetX, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, viewportSize, targetCameraRef]);
|
|
15384
|
+
}, [selectedUnitId, units, tileLayout, scale, baseOffsetX, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, viewportSize, targetCameraRef]);
|
|
15367
15385
|
React93.useEffect(() => {
|
|
15368
15386
|
const hasAnimations = units.length > 0 || validMoves.length > 0 || attackTargets.length > 0 || selectedUnitId != null || targetCameraRef.current != null || hasActiveEffects2 || pendingCount > 0 || atlasPending > 0;
|
|
15369
15387
|
draw(animTimeRef.current);
|
|
@@ -15396,13 +15414,13 @@ function IsometricCanvas({
|
|
|
15396
15414
|
const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
|
|
15397
15415
|
const adjustedX = world.x - scaledTileWidth / 2;
|
|
15398
15416
|
const adjustedY = world.y - scaledDiamondTopY - scaledFloorHeight / 2;
|
|
15399
|
-
const isoPos = screenToIso(adjustedX, adjustedY, scale, baseOffsetX);
|
|
15417
|
+
const isoPos = screenToIso(adjustedX, adjustedY, scale, baseOffsetX, tileLayout);
|
|
15400
15418
|
const tileExists = tilesProp.some((t2) => t2.x === isoPos.x && t2.y === isoPos.y);
|
|
15401
15419
|
if (tileExists) {
|
|
15402
15420
|
if (tileHoverEvent) eventBus.emit(`UI:${tileHoverEvent}`, { x: isoPos.x, y: isoPos.y });
|
|
15403
15421
|
onTileHover?.(isoPos.x, isoPos.y);
|
|
15404
15422
|
}
|
|
15405
|
-
}, [onTileHover, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, scale, baseOffsetX, tilesProp, tileHoverEvent, eventBus]);
|
|
15423
|
+
}, [onTileHover, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, tileLayout, scale, baseOffsetX, tilesProp, tileHoverEvent, eventBus]);
|
|
15406
15424
|
const handleCanvasPointerUp = React93.useCallback((e) => {
|
|
15407
15425
|
singlePointerActiveRef.current = false;
|
|
15408
15426
|
if (enableCamera) handlePointerUp();
|
|
@@ -15411,7 +15429,7 @@ function IsometricCanvas({
|
|
|
15411
15429
|
const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
|
|
15412
15430
|
const adjustedX = world.x - scaledTileWidth / 2;
|
|
15413
15431
|
const adjustedY = world.y - scaledDiamondTopY - scaledFloorHeight / 2;
|
|
15414
|
-
const isoPos = screenToIso(adjustedX, adjustedY, scale, baseOffsetX);
|
|
15432
|
+
const isoPos = screenToIso(adjustedX, adjustedY, scale, baseOffsetX, tileLayout);
|
|
15415
15433
|
const clickedUnit = units.find((u) => u.position?.x === isoPos.x && u.position?.y === isoPos.y);
|
|
15416
15434
|
if (clickedUnit && (onUnitClick || unitClickEvent)) {
|
|
15417
15435
|
if (unitClickEvent) eventBus.emit(`UI:${unitClickEvent}`, { unitId: clickedUnit.id });
|
|
@@ -15423,7 +15441,7 @@ function IsometricCanvas({
|
|
|
15423
15441
|
onTileClick?.(isoPos.x, isoPos.y);
|
|
15424
15442
|
}
|
|
15425
15443
|
}
|
|
15426
|
-
}, [enableCamera, handlePointerUp, dragDistance, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, scale, baseOffsetX, units, tilesProp, onUnitClick, onTileClick, unitClickEvent, tileClickEvent, eventBus]);
|
|
15444
|
+
}, [enableCamera, handlePointerUp, dragDistance, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, tileLayout, scale, baseOffsetX, units, tilesProp, onUnitClick, onTileClick, unitClickEvent, tileClickEvent, eventBus]);
|
|
15427
15445
|
const handleCanvasPointerLeave = React93.useCallback(() => {
|
|
15428
15446
|
handleMouseLeave();
|
|
15429
15447
|
if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
|
|
@@ -46760,6 +46778,48 @@ var init_HeroOrganism = __esm({
|
|
|
46760
46778
|
_HeroClickInterceptor.displayName = "_HeroClickInterceptor";
|
|
46761
46779
|
}
|
|
46762
46780
|
});
|
|
46781
|
+
function HexStrategyBoard({
|
|
46782
|
+
tiles,
|
|
46783
|
+
units,
|
|
46784
|
+
features,
|
|
46785
|
+
assetManifest,
|
|
46786
|
+
assetBaseUrl,
|
|
46787
|
+
scale = 0.45,
|
|
46788
|
+
showMinimap = true,
|
|
46789
|
+
enableCamera = true,
|
|
46790
|
+
tileClickEvent,
|
|
46791
|
+
unitClickEvent,
|
|
46792
|
+
isLoading,
|
|
46793
|
+
error,
|
|
46794
|
+
className
|
|
46795
|
+
}) {
|
|
46796
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("hex-strategy-board relative w-full h-full", className), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
46797
|
+
IsometricCanvas_default,
|
|
46798
|
+
{
|
|
46799
|
+
tileLayout: "hex",
|
|
46800
|
+
tiles,
|
|
46801
|
+
units,
|
|
46802
|
+
features,
|
|
46803
|
+
assetManifest,
|
|
46804
|
+
assetBaseUrl,
|
|
46805
|
+
scale,
|
|
46806
|
+
showMinimap,
|
|
46807
|
+
enableCamera,
|
|
46808
|
+
tileClickEvent,
|
|
46809
|
+
unitClickEvent,
|
|
46810
|
+
isLoading,
|
|
46811
|
+
error
|
|
46812
|
+
}
|
|
46813
|
+
) });
|
|
46814
|
+
}
|
|
46815
|
+
var init_HexStrategyBoard = __esm({
|
|
46816
|
+
"components/game/organisms/HexStrategyBoard.tsx"() {
|
|
46817
|
+
"use client";
|
|
46818
|
+
init_cn();
|
|
46819
|
+
init_IsometricCanvas();
|
|
46820
|
+
HexStrategyBoard.displayName = "HexStrategyBoard";
|
|
46821
|
+
}
|
|
46822
|
+
});
|
|
46763
46823
|
var LandingPageTemplate;
|
|
46764
46824
|
var init_LandingPageTemplate = __esm({
|
|
46765
46825
|
"components/marketing/templates/LandingPageTemplate.tsx"() {
|
|
@@ -54588,6 +54648,7 @@ var init_component_registry_generated = __esm({
|
|
|
54588
54648
|
init_HealthPanel();
|
|
54589
54649
|
init_HeroOrganism();
|
|
54590
54650
|
init_HeroSection();
|
|
54651
|
+
init_HexStrategyBoard();
|
|
54591
54652
|
init_Icon();
|
|
54592
54653
|
init_InfiniteScrollSentinel();
|
|
54593
54654
|
init_Input();
|
|
@@ -54924,6 +54985,7 @@ var init_component_registry_generated = __esm({
|
|
|
54924
54985
|
"HealthPanel": HealthPanel,
|
|
54925
54986
|
"HeroOrganism": HeroOrganism,
|
|
54926
54987
|
"HeroSection": HeroSection,
|
|
54988
|
+
"HexStrategyBoard": HexStrategyBoard,
|
|
54927
54989
|
"Icon": Icon,
|
|
54928
54990
|
"InfiniteScrollSentinel": InfiniteScrollSentinel,
|
|
54929
54991
|
"Input": Input,
|
package/dist/avl/index.js
CHANGED
|
@@ -14676,16 +14676,26 @@ var init_useUnitSpriteAtlas = __esm({
|
|
|
14676
14676
|
});
|
|
14677
14677
|
|
|
14678
14678
|
// components/game/organisms/utils/isometric.ts
|
|
14679
|
-
function isoToScreen(tileX, tileY, scale, baseOffsetX) {
|
|
14679
|
+
function isoToScreen(tileX, tileY, scale, baseOffsetX, layout = "isometric") {
|
|
14680
14680
|
const scaledTileWidth = TILE_WIDTH * scale;
|
|
14681
14681
|
const scaledFloorHeight = FLOOR_HEIGHT * scale;
|
|
14682
|
+
if (layout === "hex") {
|
|
14683
|
+
const screenX2 = tileX * scaledTileWidth + (tileY & 1) * (scaledTileWidth / 2) + baseOffsetX;
|
|
14684
|
+
const screenY2 = tileY * (scaledFloorHeight * 0.75);
|
|
14685
|
+
return { x: screenX2, y: screenY2 };
|
|
14686
|
+
}
|
|
14682
14687
|
const screenX = (tileX - tileY) * (scaledTileWidth / 2) + baseOffsetX;
|
|
14683
14688
|
const screenY = (tileX + tileY) * (scaledFloorHeight / 2);
|
|
14684
14689
|
return { x: screenX, y: screenY };
|
|
14685
14690
|
}
|
|
14686
|
-
function screenToIso(screenX, screenY, scale, baseOffsetX) {
|
|
14691
|
+
function screenToIso(screenX, screenY, scale, baseOffsetX, layout = "isometric") {
|
|
14687
14692
|
const scaledTileWidth = TILE_WIDTH * scale;
|
|
14688
14693
|
const scaledFloorHeight = FLOOR_HEIGHT * scale;
|
|
14694
|
+
if (layout === "hex") {
|
|
14695
|
+
const row = Math.round(screenY / (scaledFloorHeight * 0.75));
|
|
14696
|
+
const col = Math.round((screenX - (row & 1) * (scaledTileWidth / 2) - baseOffsetX) / scaledTileWidth);
|
|
14697
|
+
return { x: col, y: row };
|
|
14698
|
+
}
|
|
14689
14699
|
const adjustedX = screenX - baseOffsetX;
|
|
14690
14700
|
const tileX = (adjustedX / (scaledTileWidth / 2) + screenY / (scaledFloorHeight / 2)) / 2;
|
|
14691
14701
|
const tileY = (screenY / (scaledFloorHeight / 2) - adjustedX / (scaledTileWidth / 2)) / 2;
|
|
@@ -14735,6 +14745,7 @@ function IsometricCanvas({
|
|
|
14735
14745
|
tileHoverEvent,
|
|
14736
14746
|
tileLeaveEvent,
|
|
14737
14747
|
// Rendering options
|
|
14748
|
+
tileLayout = "isometric",
|
|
14738
14749
|
scale = 0.4,
|
|
14739
14750
|
debug: debug2 = false,
|
|
14740
14751
|
backgroundImage = "",
|
|
@@ -14804,13 +14815,17 @@ function IsometricCanvas({
|
|
|
14804
14815
|
);
|
|
14805
14816
|
const sortedTiles = useMemo(() => {
|
|
14806
14817
|
const tiles = [...tilesProp];
|
|
14807
|
-
|
|
14808
|
-
|
|
14809
|
-
|
|
14810
|
-
|
|
14811
|
-
|
|
14818
|
+
if (tileLayout === "hex") {
|
|
14819
|
+
tiles.sort((a, b) => a.y !== b.y ? a.y - b.y : a.x - b.x);
|
|
14820
|
+
} else {
|
|
14821
|
+
tiles.sort((a, b) => {
|
|
14822
|
+
const depthA = a.x + a.y;
|
|
14823
|
+
const depthB = b.x + b.y;
|
|
14824
|
+
return depthA !== depthB ? depthA - depthB : a.y - b.y;
|
|
14825
|
+
});
|
|
14826
|
+
}
|
|
14812
14827
|
return tiles;
|
|
14813
|
-
}, [tilesProp]);
|
|
14828
|
+
}, [tilesProp, tileLayout]);
|
|
14814
14829
|
const gridWidth = useMemo(() => {
|
|
14815
14830
|
if (sortedTiles.length === 0) return 0;
|
|
14816
14831
|
return Math.max(...sortedTiles.map((t2) => t2.x)) + 1;
|
|
@@ -14924,7 +14939,7 @@ function IsometricCanvas({
|
|
|
14924
14939
|
miniCanvas.width = mW;
|
|
14925
14940
|
miniCanvas.height = mH;
|
|
14926
14941
|
mCtx.clearRect(0, 0, mW, mH);
|
|
14927
|
-
const allScreenPos = sortedTiles.map((t2) => isoToScreen(t2.x, t2.y, scale, baseOffsetX));
|
|
14942
|
+
const allScreenPos = sortedTiles.map((t2) => isoToScreen(t2.x, t2.y, scale, baseOffsetX, tileLayout));
|
|
14928
14943
|
const minX = Math.min(...allScreenPos.map((p2) => p2.x));
|
|
14929
14944
|
const maxX = Math.max(...allScreenPos.map((p2) => p2.x + scaledTileWidth));
|
|
14930
14945
|
const minY = Math.min(...allScreenPos.map((p2) => p2.y));
|
|
@@ -14935,7 +14950,7 @@ function IsometricCanvas({
|
|
|
14935
14950
|
const offsetMx = (mW - worldW * scaleM) / 2;
|
|
14936
14951
|
const offsetMy = (mH - worldH * scaleM) / 2;
|
|
14937
14952
|
for (const tile of sortedTiles) {
|
|
14938
|
-
const pos = isoToScreen(tile.x, tile.y, scale, baseOffsetX);
|
|
14953
|
+
const pos = isoToScreen(tile.x, tile.y, scale, baseOffsetX, tileLayout);
|
|
14939
14954
|
const mx = (pos.x - minX) * scaleM + offsetMx;
|
|
14940
14955
|
const my = (pos.y - minY) * scaleM + offsetMy;
|
|
14941
14956
|
const mTileW = scaledTileWidth * scaleM;
|
|
@@ -14951,7 +14966,7 @@ function IsometricCanvas({
|
|
|
14951
14966
|
}
|
|
14952
14967
|
for (const unit of units) {
|
|
14953
14968
|
if (!unit.position) continue;
|
|
14954
|
-
const pos = isoToScreen(unit.position.x, unit.position.y, scale, baseOffsetX);
|
|
14969
|
+
const pos = isoToScreen(unit.position.x, unit.position.y, scale, baseOffsetX, tileLayout);
|
|
14955
14970
|
const mx = (pos.x + scaledTileWidth / 2 - minX) * scaleM + offsetMx;
|
|
14956
14971
|
const my = (pos.y + scaledTileHeight / 2 - minY) * scaleM + offsetMy;
|
|
14957
14972
|
mCtx.fillStyle = unit.team === "player" ? "#60a5fa" : unit.team === "enemy" ? "#f87171" : "#9ca3af";
|
|
@@ -14967,7 +14982,7 @@ function IsometricCanvas({
|
|
|
14967
14982
|
mCtx.strokeStyle = "rgba(255, 255, 255, 0.8)";
|
|
14968
14983
|
mCtx.lineWidth = 1;
|
|
14969
14984
|
mCtx.strokeRect(vLeft, vTop, vW, vH);
|
|
14970
|
-
}, [showMinimap, sortedTiles, units, scale, baseOffsetX, scaledTileWidth, scaledTileHeight, scaledFloorHeight, viewportSize, cameraRef]);
|
|
14985
|
+
}, [showMinimap, sortedTiles, units, tileLayout, scale, baseOffsetX, scaledTileWidth, scaledTileHeight, scaledFloorHeight, viewportSize, cameraRef]);
|
|
14971
14986
|
const draw = useCallback((animTime) => {
|
|
14972
14987
|
const canvas = canvasRef.current;
|
|
14973
14988
|
if (!canvas) return;
|
|
@@ -15007,7 +15022,7 @@ function IsometricCanvas({
|
|
|
15007
15022
|
const visTop = cam.y - viewportSize.height / cam.zoom;
|
|
15008
15023
|
const visBottom = cam.y + viewportSize.height * 2 / cam.zoom;
|
|
15009
15024
|
for (const tile of sortedTiles) {
|
|
15010
|
-
const pos = isoToScreen(tile.x, tile.y, scale, baseOffsetX);
|
|
15025
|
+
const pos = isoToScreen(tile.x, tile.y, scale, baseOffsetX, tileLayout);
|
|
15011
15026
|
if (pos.x + scaledTileWidth < visLeft || pos.x > visRight || pos.y + scaledTileHeight < visTop || pos.y > visBottom) {
|
|
15012
15027
|
continue;
|
|
15013
15028
|
}
|
|
@@ -15087,12 +15102,13 @@ function IsometricCanvas({
|
|
|
15087
15102
|
}
|
|
15088
15103
|
}
|
|
15089
15104
|
const sortedFeatures = [...features].sort((a, b) => {
|
|
15105
|
+
if (tileLayout === "hex") return a.y !== b.y ? a.y - b.y : a.x - b.x;
|
|
15090
15106
|
const depthA = a.x + a.y;
|
|
15091
15107
|
const depthB = b.x + b.y;
|
|
15092
15108
|
return depthA !== depthB ? depthA - depthB : a.y - b.y;
|
|
15093
15109
|
});
|
|
15094
15110
|
for (const feature of sortedFeatures) {
|
|
15095
|
-
const pos = isoToScreen(feature.x, feature.y, scale, baseOffsetX);
|
|
15111
|
+
const pos = isoToScreen(feature.x, feature.y, scale, baseOffsetX, tileLayout);
|
|
15096
15112
|
if (pos.x + scaledTileWidth < visLeft || pos.x > visRight || pos.y + scaledTileHeight < visTop || pos.y > visBottom) {
|
|
15097
15113
|
continue;
|
|
15098
15114
|
}
|
|
@@ -15127,12 +15143,13 @@ function IsometricCanvas({
|
|
|
15127
15143
|
}
|
|
15128
15144
|
const unitsWithPosition = units.filter((u) => !!u.position);
|
|
15129
15145
|
const sortedUnits = [...unitsWithPosition].sort((a, b) => {
|
|
15146
|
+
if (tileLayout === "hex") return a.position.y !== b.position.y ? a.position.y - b.position.y : a.position.x - b.position.x;
|
|
15130
15147
|
const depthA = a.position.x + a.position.y;
|
|
15131
15148
|
const depthB = b.position.x + b.position.y;
|
|
15132
15149
|
return depthA !== depthB ? depthA - depthB : a.position.y - b.position.y;
|
|
15133
15150
|
});
|
|
15134
15151
|
for (const unit of sortedUnits) {
|
|
15135
|
-
const pos = isoToScreen(unit.position.x, unit.position.y, scale, baseOffsetX);
|
|
15152
|
+
const pos = isoToScreen(unit.position.x, unit.position.y, scale, baseOffsetX, tileLayout);
|
|
15136
15153
|
if (pos.x + scaledTileWidth < visLeft || pos.x > visRight || pos.y + scaledTileHeight < visTop || pos.y > visBottom) {
|
|
15137
15154
|
continue;
|
|
15138
15155
|
}
|
|
@@ -15152,7 +15169,7 @@ function IsometricCanvas({
|
|
|
15152
15169
|
drawH = maxUnitW / ar;
|
|
15153
15170
|
}
|
|
15154
15171
|
if (unit.previousPosition && (unit.previousPosition.x !== unit.position.x || unit.previousPosition.y !== unit.position.y)) {
|
|
15155
|
-
const ghostPos = isoToScreen(unit.previousPosition.x, unit.previousPosition.y, scale, baseOffsetX);
|
|
15172
|
+
const ghostPos = isoToScreen(unit.previousPosition.x, unit.previousPosition.y, scale, baseOffsetX, tileLayout);
|
|
15156
15173
|
const ghostCenterX = ghostPos.x + scaledTileWidth / 2;
|
|
15157
15174
|
const ghostGroundY = ghostPos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
|
|
15158
15175
|
ctx.save();
|
|
@@ -15281,6 +15298,7 @@ function IsometricCanvas({
|
|
|
15281
15298
|
units,
|
|
15282
15299
|
features,
|
|
15283
15300
|
selectedUnitId,
|
|
15301
|
+
tileLayout,
|
|
15284
15302
|
scale,
|
|
15285
15303
|
debug2,
|
|
15286
15304
|
resolveTerrainSpriteUrl,
|
|
@@ -15309,14 +15327,14 @@ function IsometricCanvas({
|
|
|
15309
15327
|
if (!selectedUnitId) return;
|
|
15310
15328
|
const unit = units.find((u) => u.id === selectedUnitId);
|
|
15311
15329
|
if (!unit?.position) return;
|
|
15312
|
-
const pos = isoToScreen(unit.position.x, unit.position.y, scale, baseOffsetX);
|
|
15330
|
+
const pos = isoToScreen(unit.position.x, unit.position.y, scale, baseOffsetX, tileLayout);
|
|
15313
15331
|
const centerX = pos.x + scaledTileWidth / 2;
|
|
15314
15332
|
const centerY = pos.y + scaledDiamondTopY + scaledFloorHeight / 2;
|
|
15315
15333
|
targetCameraRef.current = {
|
|
15316
15334
|
x: centerX - viewportSize.width / 2,
|
|
15317
15335
|
y: centerY - viewportSize.height / 2
|
|
15318
15336
|
};
|
|
15319
|
-
}, [selectedUnitId, units, scale, baseOffsetX, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, viewportSize, targetCameraRef]);
|
|
15337
|
+
}, [selectedUnitId, units, tileLayout, scale, baseOffsetX, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, viewportSize, targetCameraRef]);
|
|
15320
15338
|
useEffect(() => {
|
|
15321
15339
|
const hasAnimations = units.length > 0 || validMoves.length > 0 || attackTargets.length > 0 || selectedUnitId != null || targetCameraRef.current != null || hasActiveEffects2 || pendingCount > 0 || atlasPending > 0;
|
|
15322
15340
|
draw(animTimeRef.current);
|
|
@@ -15349,13 +15367,13 @@ function IsometricCanvas({
|
|
|
15349
15367
|
const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
|
|
15350
15368
|
const adjustedX = world.x - scaledTileWidth / 2;
|
|
15351
15369
|
const adjustedY = world.y - scaledDiamondTopY - scaledFloorHeight / 2;
|
|
15352
|
-
const isoPos = screenToIso(adjustedX, adjustedY, scale, baseOffsetX);
|
|
15370
|
+
const isoPos = screenToIso(adjustedX, adjustedY, scale, baseOffsetX, tileLayout);
|
|
15353
15371
|
const tileExists = tilesProp.some((t2) => t2.x === isoPos.x && t2.y === isoPos.y);
|
|
15354
15372
|
if (tileExists) {
|
|
15355
15373
|
if (tileHoverEvent) eventBus.emit(`UI:${tileHoverEvent}`, { x: isoPos.x, y: isoPos.y });
|
|
15356
15374
|
onTileHover?.(isoPos.x, isoPos.y);
|
|
15357
15375
|
}
|
|
15358
|
-
}, [onTileHover, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, scale, baseOffsetX, tilesProp, tileHoverEvent, eventBus]);
|
|
15376
|
+
}, [onTileHover, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, tileLayout, scale, baseOffsetX, tilesProp, tileHoverEvent, eventBus]);
|
|
15359
15377
|
const handleCanvasPointerUp = useCallback((e) => {
|
|
15360
15378
|
singlePointerActiveRef.current = false;
|
|
15361
15379
|
if (enableCamera) handlePointerUp();
|
|
@@ -15364,7 +15382,7 @@ function IsometricCanvas({
|
|
|
15364
15382
|
const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
|
|
15365
15383
|
const adjustedX = world.x - scaledTileWidth / 2;
|
|
15366
15384
|
const adjustedY = world.y - scaledDiamondTopY - scaledFloorHeight / 2;
|
|
15367
|
-
const isoPos = screenToIso(adjustedX, adjustedY, scale, baseOffsetX);
|
|
15385
|
+
const isoPos = screenToIso(adjustedX, adjustedY, scale, baseOffsetX, tileLayout);
|
|
15368
15386
|
const clickedUnit = units.find((u) => u.position?.x === isoPos.x && u.position?.y === isoPos.y);
|
|
15369
15387
|
if (clickedUnit && (onUnitClick || unitClickEvent)) {
|
|
15370
15388
|
if (unitClickEvent) eventBus.emit(`UI:${unitClickEvent}`, { unitId: clickedUnit.id });
|
|
@@ -15376,7 +15394,7 @@ function IsometricCanvas({
|
|
|
15376
15394
|
onTileClick?.(isoPos.x, isoPos.y);
|
|
15377
15395
|
}
|
|
15378
15396
|
}
|
|
15379
|
-
}, [enableCamera, handlePointerUp, dragDistance, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, scale, baseOffsetX, units, tilesProp, onUnitClick, onTileClick, unitClickEvent, tileClickEvent, eventBus]);
|
|
15397
|
+
}, [enableCamera, handlePointerUp, dragDistance, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, tileLayout, scale, baseOffsetX, units, tilesProp, onUnitClick, onTileClick, unitClickEvent, tileClickEvent, eventBus]);
|
|
15380
15398
|
const handleCanvasPointerLeave = useCallback(() => {
|
|
15381
15399
|
handleMouseLeave();
|
|
15382
15400
|
if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
|
|
@@ -46713,6 +46731,48 @@ var init_HeroOrganism = __esm({
|
|
|
46713
46731
|
_HeroClickInterceptor.displayName = "_HeroClickInterceptor";
|
|
46714
46732
|
}
|
|
46715
46733
|
});
|
|
46734
|
+
function HexStrategyBoard({
|
|
46735
|
+
tiles,
|
|
46736
|
+
units,
|
|
46737
|
+
features,
|
|
46738
|
+
assetManifest,
|
|
46739
|
+
assetBaseUrl,
|
|
46740
|
+
scale = 0.45,
|
|
46741
|
+
showMinimap = true,
|
|
46742
|
+
enableCamera = true,
|
|
46743
|
+
tileClickEvent,
|
|
46744
|
+
unitClickEvent,
|
|
46745
|
+
isLoading,
|
|
46746
|
+
error,
|
|
46747
|
+
className
|
|
46748
|
+
}) {
|
|
46749
|
+
return /* @__PURE__ */ jsx("div", { className: cn("hex-strategy-board relative w-full h-full", className), children: /* @__PURE__ */ jsx(
|
|
46750
|
+
IsometricCanvas_default,
|
|
46751
|
+
{
|
|
46752
|
+
tileLayout: "hex",
|
|
46753
|
+
tiles,
|
|
46754
|
+
units,
|
|
46755
|
+
features,
|
|
46756
|
+
assetManifest,
|
|
46757
|
+
assetBaseUrl,
|
|
46758
|
+
scale,
|
|
46759
|
+
showMinimap,
|
|
46760
|
+
enableCamera,
|
|
46761
|
+
tileClickEvent,
|
|
46762
|
+
unitClickEvent,
|
|
46763
|
+
isLoading,
|
|
46764
|
+
error
|
|
46765
|
+
}
|
|
46766
|
+
) });
|
|
46767
|
+
}
|
|
46768
|
+
var init_HexStrategyBoard = __esm({
|
|
46769
|
+
"components/game/organisms/HexStrategyBoard.tsx"() {
|
|
46770
|
+
"use client";
|
|
46771
|
+
init_cn();
|
|
46772
|
+
init_IsometricCanvas();
|
|
46773
|
+
HexStrategyBoard.displayName = "HexStrategyBoard";
|
|
46774
|
+
}
|
|
46775
|
+
});
|
|
46716
46776
|
var LandingPageTemplate;
|
|
46717
46777
|
var init_LandingPageTemplate = __esm({
|
|
46718
46778
|
"components/marketing/templates/LandingPageTemplate.tsx"() {
|
|
@@ -54541,6 +54601,7 @@ var init_component_registry_generated = __esm({
|
|
|
54541
54601
|
init_HealthPanel();
|
|
54542
54602
|
init_HeroOrganism();
|
|
54543
54603
|
init_HeroSection();
|
|
54604
|
+
init_HexStrategyBoard();
|
|
54544
54605
|
init_Icon();
|
|
54545
54606
|
init_InfiniteScrollSentinel();
|
|
54546
54607
|
init_Input();
|
|
@@ -54877,6 +54938,7 @@ var init_component_registry_generated = __esm({
|
|
|
54877
54938
|
"HealthPanel": HealthPanel,
|
|
54878
54939
|
"HeroOrganism": HeroOrganism,
|
|
54879
54940
|
"HeroSection": HeroSection,
|
|
54941
|
+
"HexStrategyBoard": HexStrategyBoard,
|
|
54880
54942
|
"Icon": Icon,
|
|
54881
54943
|
"InfiniteScrollSentinel": InfiniteScrollSentinel,
|
|
54882
54944
|
"Input": Input,
|
|
@@ -27,6 +27,7 @@ import * as React from 'react';
|
|
|
27
27
|
import type { AssetUrl, EventEmit } from '@almadar/core';
|
|
28
28
|
import type { IsometricTile, IsometricUnit, IsometricFeature } from '../organisms/types/isometric';
|
|
29
29
|
import type { ResolvedFrame } from '../organisms/types/spriteAnimation';
|
|
30
|
+
import type { TileLayout } from '../organisms/utils/isometric';
|
|
30
31
|
import type { UiError } from '../../core/atoms/types';
|
|
31
32
|
/** Event Contract:
|
|
32
33
|
* Emits: UI:TILE_CLICK
|
|
@@ -79,6 +80,8 @@ export interface IsometricCanvasProps {
|
|
|
79
80
|
}>;
|
|
80
81
|
/** Declarative event: emits UI:{tileLeaveEvent} with {} on tile leave */
|
|
81
82
|
tileLeaveEvent?: EventEmit<Record<string, never>>;
|
|
83
|
+
/** Tile layout projection: 'isometric' (default 2:1 diamond) or 'hex' (pointy-top offset rows) */
|
|
84
|
+
tileLayout?: TileLayout;
|
|
82
85
|
/** Render scale (0.4 = 40% zoom) */
|
|
83
86
|
scale?: number;
|
|
84
87
|
/** Show debug grid lines and coordinates */
|
|
@@ -129,7 +132,7 @@ export interface IsometricCanvasProps {
|
|
|
129
132
|
effects?: Record<string, string>;
|
|
130
133
|
};
|
|
131
134
|
}
|
|
132
|
-
export declare function IsometricCanvas({ className, isLoading, error, tiles: _tilesPropRaw, units: _unitsPropRaw, features: _featuresPropRaw, selectedUnitId, validMoves, attackTargets, hoveredTile, onTileClick, onUnitClick, onTileHover, onTileLeave, tileClickEvent, unitClickEvent, tileHoverEvent, tileLeaveEvent, scale, debug, backgroundImage, showMinimap, enableCamera, unitScale, spriteHeightRatio, spriteMaxWidthRatio, getTerrainSprite, getFeatureSprite, getUnitSprite, resolveUnitFrame, effectSpriteUrls, onDrawEffects, hasActiveEffects, diamondTopY: diamondTopYProp, assetBaseUrl, assetManifest, }: IsometricCanvasProps): React.JSX.Element;
|
|
135
|
+
export declare function IsometricCanvas({ className, isLoading, error, tiles: _tilesPropRaw, units: _unitsPropRaw, features: _featuresPropRaw, selectedUnitId, validMoves, attackTargets, hoveredTile, onTileClick, onUnitClick, onTileHover, onTileLeave, tileClickEvent, unitClickEvent, tileHoverEvent, tileLeaveEvent, tileLayout, scale, debug, backgroundImage, showMinimap, enableCamera, unitScale, spriteHeightRatio, spriteMaxWidthRatio, getTerrainSprite, getFeatureSprite, getUnitSprite, resolveUnitFrame, effectSpriteUrls, onDrawEffects, hasActiveEffects, diamondTopY: diamondTopYProp, assetBaseUrl, assetManifest, }: IsometricCanvasProps): React.JSX.Element;
|
|
133
136
|
export declare namespace IsometricCanvas {
|
|
134
137
|
var displayName: string;
|
|
135
138
|
}
|
|
@@ -28,4 +28,5 @@ export { GameMenu, type GameMenuProps, type MenuOption } from './GameMenu';
|
|
|
28
28
|
export { GameOverScreen, type GameOverScreenProps, type GameOverStat, type GameOverAction } from './GameOverScreen';
|
|
29
29
|
export { PlatformerCanvas, type PlatformerCanvasProps, type PlatformerPlatform, type PlatformerPlayer } from './PlatformerCanvas';
|
|
30
30
|
export { IsometricCanvas, type IsometricCanvasProps } from './IsometricCanvas';
|
|
31
|
+
export type { TileLayout } from '../organisms/utils/isometric';
|
|
31
32
|
export type { IsometricTile, IsometricUnit, IsometricFeature } from '../organisms/types/isometric';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { AssetUrl, EventEmit } from '@almadar/core';
|
|
3
|
+
import type { IsometricTile, IsometricUnit, IsometricFeature } from './types/isometric';
|
|
4
|
+
import type { DisplayStateProps } from '../../core/organisms/types';
|
|
5
|
+
import type { IsometricCanvasProps } from '../molecules/IsometricCanvas';
|
|
6
|
+
export interface HexStrategyBoardProps extends DisplayStateProps {
|
|
7
|
+
/** Hex grid tiles */
|
|
8
|
+
tiles?: IsometricTile[];
|
|
9
|
+
/** Units on the board */
|
|
10
|
+
units?: IsometricUnit[];
|
|
11
|
+
/** Features (resources, structures, etc.) on the board */
|
|
12
|
+
features?: IsometricFeature[];
|
|
13
|
+
/** Asset sprite manifest (same shape as IsometricCanvas.assetManifest) */
|
|
14
|
+
assetManifest?: IsometricCanvasProps['assetManifest'];
|
|
15
|
+
/** Base URL prepended to manifest sprite paths */
|
|
16
|
+
assetBaseUrl?: AssetUrl;
|
|
17
|
+
/** Render scale */
|
|
18
|
+
scale?: number;
|
|
19
|
+
/** Show minimap overlay */
|
|
20
|
+
showMinimap?: boolean;
|
|
21
|
+
/** Enable camera pan/zoom controls */
|
|
22
|
+
enableCamera?: boolean;
|
|
23
|
+
/** Declarative event: emits UI:{tileClickEvent} with { x, y } on tile click */
|
|
24
|
+
tileClickEvent?: EventEmit<{
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
}>;
|
|
28
|
+
/** Declarative event: emits UI:{unitClickEvent} with { unitId } on unit click */
|
|
29
|
+
unitClickEvent?: EventEmit<{
|
|
30
|
+
unitId: string;
|
|
31
|
+
}>;
|
|
32
|
+
}
|
|
33
|
+
export declare function HexStrategyBoard({ tiles, units, features, assetManifest, assetBaseUrl, scale, showMinimap, enableCamera, tileClickEvent, unitClickEvent, isLoading, error, className, }: HexStrategyBoardProps): React.ReactElement;
|
|
34
|
+
export declare namespace HexStrategyBoard {
|
|
35
|
+
var displayName: string;
|
|
36
|
+
}
|
|
37
|
+
export default HexStrategyBoard;
|
|
@@ -18,6 +18,7 @@ export { useSpriteAnimations, type UseSpriteAnimationsResult, type UseSpriteAnim
|
|
|
18
18
|
export { usePhysics2D, type UsePhysics2DOptions, type UsePhysics2DReturn, } from './hooks/usePhysics2D';
|
|
19
19
|
export { PhysicsManager, type Physics2DState, type PhysicsBounds, type PhysicsConfig, } from './managers/PhysicsManager';
|
|
20
20
|
export { isoToScreen, screenToIso, TILE_WIDTH, TILE_HEIGHT, FLOOR_HEIGHT, DIAMOND_TOP_Y, FEATURE_COLORS, } from './utils/isometric';
|
|
21
|
+
export type { TileLayout } from './utils/isometric';
|
|
21
22
|
export { inferDirection, resolveSheetDirection, getCurrentFrame, resolveFrame, createUnitAnimationState, transitionAnimation, tickAnimationState, } from './utils/spriteAnimation';
|
|
22
23
|
export { SPRITE_SHEET_LAYOUT, SHEET_COLUMNS } from './utils/spriteSheetConstants';
|
|
23
24
|
export { BattleBoard, type BattleBoardProps, type BattlePhase, type BattleSlotContext, } from './BattleBoard';
|
|
@@ -33,6 +34,7 @@ export { CityBuilderBoard, type CityBuilderBoardProps, } from './CityBuilderBoar
|
|
|
33
34
|
export { GameBoard3D, type GameBoard3DProps, } from './GameBoard3D';
|
|
34
35
|
export { VisualNovelBoard, type VisualNovelBoardProps, type VisualNovelNode, type VisualNovelChoice, } from './VisualNovelBoard';
|
|
35
36
|
export { CardBattlerBoard, type CardBattlerBoardProps, type CardBattlerCard, } from './CardBattlerBoard';
|
|
37
|
+
export { HexStrategyBoard, type HexStrategyBoardProps, } from './HexStrategyBoard';
|
|
36
38
|
export { TraitStateViewer, type TraitStateViewerProps, type TraitStateMachineDefinition, type TraitTransition, } from './TraitStateViewer';
|
|
37
39
|
export { TraitSlot, type TraitSlotProps, type SlotItemData, } from './TraitSlot';
|
|
38
40
|
export { CollapsibleSection, EditorSlider, EditorSelect, EditorCheckbox, EditorTextInput, StatusBar, TerrainPalette, EditorToolbar, TERRAIN_COLORS, FEATURE_TYPES, type EditorMode, type CollapsibleSectionProps, type EditorSliderProps, type EditorSelectProps, type EditorCheckboxProps, type EditorTextInputProps, type StatusBarProps, type TerrainPaletteProps, type EditorToolbarProps, } from './editor';
|