@almadar/ui 5.57.0 → 5.59.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 +192 -29
- package/dist/avl/index.js +192 -29
- package/dist/components/core/molecules/GraphCanvas.d.ts +6 -0
- package/dist/components/game/organisms/TowerDefenseBoard.d.ts +11 -1
- package/dist/components/index.cjs +192 -29
- package/dist/components/index.js +192 -29
- package/dist/providers/index.cjs +192 -29
- package/dist/providers/index.js +192 -29
- package/dist/runtime/index.cjs +192 -29
- package/dist/runtime/index.js +192 -29
- package/package.json +1 -1
|
@@ -29941,13 +29941,13 @@ var init_MapView = __esm({
|
|
|
29941
29941
|
shadowSize: [41, 41]
|
|
29942
29942
|
});
|
|
29943
29943
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
29944
|
-
const { useEffect:
|
|
29944
|
+
const { useEffect: useEffect81, useRef: useRef78, useCallback: useCallback120, useState: useState110 } = React76__namespace.default;
|
|
29945
29945
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
29946
29946
|
const { useEventBus: useEventBus3 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
29947
29947
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
29948
29948
|
const map = useMap();
|
|
29949
29949
|
const prevRef = useRef78({ centerLat, centerLng, zoom });
|
|
29950
|
-
|
|
29950
|
+
useEffect81(() => {
|
|
29951
29951
|
const prev = prevRef.current;
|
|
29952
29952
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
29953
29953
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -29958,7 +29958,7 @@ var init_MapView = __esm({
|
|
|
29958
29958
|
}
|
|
29959
29959
|
function MapClickHandler({ onMapClick }) {
|
|
29960
29960
|
const map = useMap();
|
|
29961
|
-
|
|
29961
|
+
useEffect81(() => {
|
|
29962
29962
|
if (!onMapClick) return;
|
|
29963
29963
|
const handler = (e) => {
|
|
29964
29964
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -38419,6 +38419,9 @@ var init_GraphCanvas = __esm({
|
|
|
38419
38419
|
actions,
|
|
38420
38420
|
onNodeClick,
|
|
38421
38421
|
nodeClickEvent,
|
|
38422
|
+
selectedNodeId,
|
|
38423
|
+
repulsion = 800,
|
|
38424
|
+
linkDistance = 100,
|
|
38422
38425
|
layout = "force",
|
|
38423
38426
|
entity,
|
|
38424
38427
|
isLoading = false,
|
|
@@ -38434,6 +38437,35 @@ var init_GraphCanvas = __esm({
|
|
|
38434
38437
|
const [hoveredNode, setHoveredNode] = React76.useState(null);
|
|
38435
38438
|
const nodesRef = React76.useRef([]);
|
|
38436
38439
|
const [, forceUpdate] = React76.useState(0);
|
|
38440
|
+
const interactionRef = React76.useRef({
|
|
38441
|
+
mode: "none",
|
|
38442
|
+
dragNodeId: null,
|
|
38443
|
+
startMouse: { x: 0, y: 0 },
|
|
38444
|
+
startOffset: { x: 0, y: 0 },
|
|
38445
|
+
downPos: { x: 0, y: 0 }
|
|
38446
|
+
});
|
|
38447
|
+
const toCoords = React76.useCallback(
|
|
38448
|
+
(e) => {
|
|
38449
|
+
const canvas = canvasRef.current;
|
|
38450
|
+
if (!canvas) return null;
|
|
38451
|
+
const rect = canvas.getBoundingClientRect();
|
|
38452
|
+
const screenX = e.clientX - rect.left;
|
|
38453
|
+
const screenY = e.clientY - rect.top;
|
|
38454
|
+
return {
|
|
38455
|
+
screenX,
|
|
38456
|
+
screenY,
|
|
38457
|
+
graphX: (screenX - offset.x) / zoom,
|
|
38458
|
+
graphY: (screenY - offset.y) / zoom
|
|
38459
|
+
};
|
|
38460
|
+
},
|
|
38461
|
+
[offset, zoom]
|
|
38462
|
+
);
|
|
38463
|
+
const nodeAt = React76.useCallback((graphX, graphY) => {
|
|
38464
|
+
return nodesRef.current.find((n) => {
|
|
38465
|
+
const dist = Math.sqrt((n.x - graphX) ** 2 + (n.y - graphY) ** 2);
|
|
38466
|
+
return dist < (n.size || 8) + 4;
|
|
38467
|
+
});
|
|
38468
|
+
}, []);
|
|
38437
38469
|
const handleAction = React76.useCallback(
|
|
38438
38470
|
(action) => {
|
|
38439
38471
|
if (action.event) {
|
|
@@ -38499,7 +38531,7 @@ var init_GraphCanvas = __esm({
|
|
|
38499
38531
|
const dx = nodes[j].x - nodes[i].x;
|
|
38500
38532
|
const dy = nodes[j].y - nodes[i].y;
|
|
38501
38533
|
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
38502
|
-
const force =
|
|
38534
|
+
const force = repulsion / (dist * dist);
|
|
38503
38535
|
const fx = dx / dist * force;
|
|
38504
38536
|
const fy = dy / dist * force;
|
|
38505
38537
|
nodes[i].fx -= fx;
|
|
@@ -38515,7 +38547,7 @@ var init_GraphCanvas = __esm({
|
|
|
38515
38547
|
const dx = target.x - source.x;
|
|
38516
38548
|
const dy = target.y - source.y;
|
|
38517
38549
|
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
38518
|
-
const force = (dist -
|
|
38550
|
+
const force = (dist - linkDistance) * 0.05;
|
|
38519
38551
|
const fx = dx / dist * force;
|
|
38520
38552
|
const fy = dy / dist * force;
|
|
38521
38553
|
source.fx += fx;
|
|
@@ -38549,7 +38581,7 @@ var init_GraphCanvas = __esm({
|
|
|
38549
38581
|
return () => {
|
|
38550
38582
|
cancelAnimationFrame(animRef.current);
|
|
38551
38583
|
};
|
|
38552
|
-
}, [propNodes, propEdges, layout]);
|
|
38584
|
+
}, [propNodes, propEdges, layout, repulsion, linkDistance]);
|
|
38553
38585
|
React76.useEffect(() => {
|
|
38554
38586
|
const canvas = canvasRef.current;
|
|
38555
38587
|
if (!canvas) return;
|
|
@@ -38585,18 +38617,25 @@ var init_GraphCanvas = __esm({
|
|
|
38585
38617
|
const size = node.size || 8;
|
|
38586
38618
|
const color = node.color || getGroupColor(node.group, groups);
|
|
38587
38619
|
const isHovered = hoveredNode === node.id;
|
|
38620
|
+
const isSelected = selectedNodeId !== void 0 && node.id === selectedNodeId;
|
|
38621
|
+
const radius = isSelected ? size + 4 : isHovered ? size + 2 : size;
|
|
38588
38622
|
ctx.beginPath();
|
|
38589
|
-
ctx.arc(node.x, node.y,
|
|
38623
|
+
ctx.arc(node.x, node.y, radius, 0, Math.PI * 2);
|
|
38590
38624
|
ctx.fillStyle = color;
|
|
38591
38625
|
ctx.fill();
|
|
38592
|
-
|
|
38593
|
-
|
|
38626
|
+
if (isSelected) {
|
|
38627
|
+
ctx.strokeStyle = "var(--color-accent)";
|
|
38628
|
+
ctx.lineWidth = 3;
|
|
38629
|
+
} else {
|
|
38630
|
+
ctx.strokeStyle = isHovered ? "#ffffff" : "#00000020";
|
|
38631
|
+
ctx.lineWidth = isHovered ? 2 : 1;
|
|
38632
|
+
}
|
|
38594
38633
|
ctx.stroke();
|
|
38595
38634
|
if (showLabels && node.label) {
|
|
38596
38635
|
ctx.fillStyle = "#666666";
|
|
38597
|
-
ctx.font = `${isHovered ? "bold " : ""}10px system-ui`;
|
|
38636
|
+
ctx.font = `${isSelected || isHovered ? "bold " : ""}10px system-ui`;
|
|
38598
38637
|
ctx.textAlign = "center";
|
|
38599
|
-
ctx.fillText(node.label, node.x, node.y +
|
|
38638
|
+
ctx.fillText(node.label, node.x, node.y + radius + 12);
|
|
38600
38639
|
}
|
|
38601
38640
|
}
|
|
38602
38641
|
ctx.restore();
|
|
@@ -38607,6 +38646,97 @@ var init_GraphCanvas = __esm({
|
|
|
38607
38646
|
setZoom(1);
|
|
38608
38647
|
setOffset({ x: 0, y: 0 });
|
|
38609
38648
|
}, []);
|
|
38649
|
+
const handleWheel = React76.useCallback(
|
|
38650
|
+
(e) => {
|
|
38651
|
+
if (!interactive) return;
|
|
38652
|
+
e.preventDefault();
|
|
38653
|
+
const coords = toCoords(e);
|
|
38654
|
+
if (!coords) return;
|
|
38655
|
+
const oldZoom = zoom;
|
|
38656
|
+
const factor = e.deltaY < 0 ? 1.1 : 1 / 1.1;
|
|
38657
|
+
const newZoom = Math.max(0.3, Math.min(3, oldZoom * factor));
|
|
38658
|
+
if (newZoom === oldZoom) return;
|
|
38659
|
+
setOffset((o) => ({
|
|
38660
|
+
x: coords.screenX - (coords.screenX - o.x) * (newZoom / oldZoom),
|
|
38661
|
+
y: coords.screenY - (coords.screenY - o.y) * (newZoom / oldZoom)
|
|
38662
|
+
}));
|
|
38663
|
+
setZoom(newZoom);
|
|
38664
|
+
},
|
|
38665
|
+
[interactive, toCoords, zoom]
|
|
38666
|
+
);
|
|
38667
|
+
const handleMouseDown = React76.useCallback(
|
|
38668
|
+
(e) => {
|
|
38669
|
+
const coords = toCoords(e);
|
|
38670
|
+
if (!coords) return;
|
|
38671
|
+
const node = nodeAt(coords.graphX, coords.graphY);
|
|
38672
|
+
const state = interactionRef.current;
|
|
38673
|
+
state.downPos = { x: e.clientX, y: e.clientY };
|
|
38674
|
+
state.startMouse = { x: e.clientX, y: e.clientY };
|
|
38675
|
+
state.startOffset = { ...offset };
|
|
38676
|
+
if (draggable && node) {
|
|
38677
|
+
state.mode = "dragging";
|
|
38678
|
+
state.dragNodeId = node.id;
|
|
38679
|
+
} else if (interactive) {
|
|
38680
|
+
state.mode = "panning";
|
|
38681
|
+
state.dragNodeId = null;
|
|
38682
|
+
} else {
|
|
38683
|
+
state.mode = "none";
|
|
38684
|
+
state.dragNodeId = null;
|
|
38685
|
+
}
|
|
38686
|
+
},
|
|
38687
|
+
[toCoords, nodeAt, draggable, interactive, offset]
|
|
38688
|
+
);
|
|
38689
|
+
const handleMouseMove = React76.useCallback(
|
|
38690
|
+
(e) => {
|
|
38691
|
+
const state = interactionRef.current;
|
|
38692
|
+
if (state.mode === "panning") {
|
|
38693
|
+
const dx = e.clientX - state.startMouse.x;
|
|
38694
|
+
const dy = e.clientY - state.startMouse.y;
|
|
38695
|
+
setOffset({ x: state.startOffset.x + dx, y: state.startOffset.y + dy });
|
|
38696
|
+
return;
|
|
38697
|
+
}
|
|
38698
|
+
if (state.mode === "dragging" && state.dragNodeId) {
|
|
38699
|
+
const coords2 = toCoords(e);
|
|
38700
|
+
if (!coords2) return;
|
|
38701
|
+
const node2 = nodesRef.current.find((n) => n.id === state.dragNodeId);
|
|
38702
|
+
if (node2) {
|
|
38703
|
+
node2.x = coords2.graphX;
|
|
38704
|
+
node2.y = coords2.graphY;
|
|
38705
|
+
node2.vx = 0;
|
|
38706
|
+
node2.vy = 0;
|
|
38707
|
+
forceUpdate((n) => n + 1);
|
|
38708
|
+
}
|
|
38709
|
+
return;
|
|
38710
|
+
}
|
|
38711
|
+
const coords = toCoords(e);
|
|
38712
|
+
if (!coords) return;
|
|
38713
|
+
const node = nodeAt(coords.graphX, coords.graphY);
|
|
38714
|
+
setHoveredNode(node?.id ?? null);
|
|
38715
|
+
},
|
|
38716
|
+
[toCoords, nodeAt]
|
|
38717
|
+
);
|
|
38718
|
+
const handleMouseUp = React76.useCallback(
|
|
38719
|
+
(e) => {
|
|
38720
|
+
const state = interactionRef.current;
|
|
38721
|
+
const moved = Math.abs(e.clientX - state.downPos.x) + Math.abs(e.clientY - state.downPos.y);
|
|
38722
|
+
state.mode = "none";
|
|
38723
|
+
state.dragNodeId = null;
|
|
38724
|
+
if (moved < 4) {
|
|
38725
|
+
const coords = toCoords(e);
|
|
38726
|
+
if (!coords) return;
|
|
38727
|
+
const node = nodeAt(coords.graphX, coords.graphY);
|
|
38728
|
+
if (node) {
|
|
38729
|
+
handleNodeClick(node);
|
|
38730
|
+
}
|
|
38731
|
+
}
|
|
38732
|
+
},
|
|
38733
|
+
[toCoords, nodeAt, handleNodeClick]
|
|
38734
|
+
);
|
|
38735
|
+
const handleMouseLeave = React76.useCallback(() => {
|
|
38736
|
+
interactionRef.current.mode = "none";
|
|
38737
|
+
interactionRef.current.dragNodeId = null;
|
|
38738
|
+
setHoveredNode(null);
|
|
38739
|
+
}, []);
|
|
38610
38740
|
if (isLoading) {
|
|
38611
38741
|
return /* @__PURE__ */ jsxRuntime.jsx(exports.LoadingState, { message: t("common.loading"), className });
|
|
38612
38742
|
}
|
|
@@ -38668,20 +38798,11 @@ var init_GraphCanvas = __esm({
|
|
|
38668
38798
|
height,
|
|
38669
38799
|
className: "w-full cursor-grab active:cursor-grabbing",
|
|
38670
38800
|
style: { height },
|
|
38671
|
-
|
|
38672
|
-
|
|
38673
|
-
|
|
38674
|
-
|
|
38675
|
-
|
|
38676
|
-
const y = (e.clientY - rect.top - offset.y) / zoom;
|
|
38677
|
-
const clickedNode = nodesRef.current.find((n) => {
|
|
38678
|
-
const dist = Math.sqrt((n.x - x) ** 2 + (n.y - y) ** 2);
|
|
38679
|
-
return dist < (n.size || 8) + 4;
|
|
38680
|
-
});
|
|
38681
|
-
if (clickedNode) {
|
|
38682
|
-
handleNodeClick(clickedNode);
|
|
38683
|
-
}
|
|
38684
|
-
}
|
|
38801
|
+
onWheel: handleWheel,
|
|
38802
|
+
onMouseDown: handleMouseDown,
|
|
38803
|
+
onMouseMove: handleMouseMove,
|
|
38804
|
+
onMouseUp: handleMouseUp,
|
|
38805
|
+
onMouseLeave: handleMouseLeave
|
|
38685
38806
|
}
|
|
38686
38807
|
) }),
|
|
38687
38808
|
groups.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(exports.HStack, { gap: "md", className: "px-4 py-2 border-t border-border", wrap: true, children: groups.map((group, idx) => /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", align: "center", children: [
|
|
@@ -50500,12 +50621,25 @@ function pathToFeatures(path) {
|
|
|
50500
50621
|
sprite: `${CDN6}world-map/road_straight.png`
|
|
50501
50622
|
}));
|
|
50502
50623
|
}
|
|
50624
|
+
function heroToUnit(hero) {
|
|
50625
|
+
return {
|
|
50626
|
+
id: hero.id,
|
|
50627
|
+
position: { x: hero.x, y: hero.y },
|
|
50628
|
+
name: "Hero",
|
|
50629
|
+
team: "player",
|
|
50630
|
+
sprite: HERO_SPRITE,
|
|
50631
|
+
unitType: "amir",
|
|
50632
|
+
health: 1,
|
|
50633
|
+
maxHealth: 1
|
|
50634
|
+
};
|
|
50635
|
+
}
|
|
50503
50636
|
function TowerDefenseBoard({
|
|
50504
50637
|
entity,
|
|
50505
50638
|
tiles: propTiles,
|
|
50506
50639
|
path: propPath,
|
|
50507
50640
|
towers: propTowers,
|
|
50508
50641
|
creeps: propCreeps,
|
|
50642
|
+
hero: propHero,
|
|
50509
50643
|
gold: propGold,
|
|
50510
50644
|
lives: propLives,
|
|
50511
50645
|
wave: propWave,
|
|
@@ -50521,6 +50655,7 @@ function TowerDefenseBoard({
|
|
|
50521
50655
|
startWaveEvent,
|
|
50522
50656
|
playAgainEvent,
|
|
50523
50657
|
gameEndEvent,
|
|
50658
|
+
moveHeroEvent,
|
|
50524
50659
|
className
|
|
50525
50660
|
}) {
|
|
50526
50661
|
const board = boardEntity(entity) ?? {};
|
|
@@ -50532,6 +50667,7 @@ function TowerDefenseBoard({
|
|
|
50532
50667
|
const path = rawPath.length > 0 ? rawPath : DEFAULT_TD_PATH;
|
|
50533
50668
|
const towers = propTowers ?? rows(board.towers);
|
|
50534
50669
|
const creeps = propCreeps ?? rows(board.creeps);
|
|
50670
|
+
const hero = propHero ?? { id: "hero", x: 8, y: 8 };
|
|
50535
50671
|
const gold = propGold ?? num(board.gold, 100);
|
|
50536
50672
|
const lives = propLives ?? num(board.lives, 20);
|
|
50537
50673
|
const wave = propWave ?? num(board.wave, 1);
|
|
@@ -50549,6 +50685,31 @@ function TowerDefenseBoard({
|
|
|
50549
50685
|
if (result === "none") {
|
|
50550
50686
|
emittedGameEnd.current = false;
|
|
50551
50687
|
}
|
|
50688
|
+
const moveHeroEventRef = React76.useRef(moveHeroEvent);
|
|
50689
|
+
moveHeroEventRef.current = moveHeroEvent;
|
|
50690
|
+
const resultRef = React76.useRef(result);
|
|
50691
|
+
resultRef.current = result;
|
|
50692
|
+
React76.useEffect(() => {
|
|
50693
|
+
function onKeyDown(e) {
|
|
50694
|
+
const evt = moveHeroEventRef.current;
|
|
50695
|
+
if (!evt || resultRef.current !== "none") return;
|
|
50696
|
+
let dx = 0;
|
|
50697
|
+
let dy = 0;
|
|
50698
|
+
if (e.key === "ArrowUp") {
|
|
50699
|
+
dy = -1;
|
|
50700
|
+
} else if (e.key === "ArrowDown") {
|
|
50701
|
+
dy = 1;
|
|
50702
|
+
} else if (e.key === "ArrowLeft") {
|
|
50703
|
+
dx = -1;
|
|
50704
|
+
} else if (e.key === "ArrowRight") {
|
|
50705
|
+
dx = 1;
|
|
50706
|
+
} else return;
|
|
50707
|
+
e.preventDefault();
|
|
50708
|
+
eventBus.emit(`UI:${evt}`, { dx, dy });
|
|
50709
|
+
}
|
|
50710
|
+
window.addEventListener("keydown", onKeyDown);
|
|
50711
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
50712
|
+
}, [eventBus]);
|
|
50552
50713
|
const towerPositions = React76.useMemo(() => new Set(towers.map((t2) => `${t2.x},${t2.y}`)), [towers]);
|
|
50553
50714
|
const pathPositions = React76.useMemo(() => new Set(path.map((p2) => `${p2.x},${p2.y}`)), [path]);
|
|
50554
50715
|
const validMoves = React76.useMemo(() => {
|
|
@@ -50560,7 +50721,8 @@ function TowerDefenseBoard({
|
|
|
50560
50721
|
const isoTiles = React76.useMemo(() => tilesToIso(tiles), [tiles]);
|
|
50561
50722
|
const towerUnits = React76.useMemo(() => towersToUnits(towers), [towers]);
|
|
50562
50723
|
const creepUnits = React76.useMemo(() => creepsToUnits(creeps), [creeps]);
|
|
50563
|
-
const
|
|
50724
|
+
const heroUnit = React76.useMemo(() => heroToUnit(hero), [hero]);
|
|
50725
|
+
const isoUnits = React76.useMemo(() => [...towerUnits, ...creepUnits, heroUnit], [towerUnits, creepUnits, heroUnit]);
|
|
50564
50726
|
const pathFeatures = React76.useMemo(() => pathToFeatures(path), [path]);
|
|
50565
50727
|
const handleTileClick = React76.useCallback((x, y) => {
|
|
50566
50728
|
if (result !== "none") return;
|
|
@@ -50659,7 +50821,7 @@ function TowerDefenseBoard({
|
|
|
50659
50821
|
] }) })
|
|
50660
50822
|
] });
|
|
50661
50823
|
}
|
|
50662
|
-
var CDN6, TD_GRID_W, TD_GRID_H, TERRAIN_SPRITES, DEFAULT_TD_PATH, DEFAULT_TD_TILES, TOWER_SPRITE, CREEP_SPRITE;
|
|
50824
|
+
var CDN6, TD_GRID_W, TD_GRID_H, TERRAIN_SPRITES, DEFAULT_TD_PATH, DEFAULT_TD_TILES, TOWER_SPRITE, CREEP_SPRITE, HERO_SPRITE;
|
|
50663
50825
|
var init_TowerDefenseBoard = __esm({
|
|
50664
50826
|
"components/game/organisms/TowerDefenseBoard.tsx"() {
|
|
50665
50827
|
"use client";
|
|
@@ -50733,8 +50895,9 @@ var init_TowerDefenseBoard = __esm({
|
|
|
50733
50895
|
{ x: 13, y: 15 }
|
|
50734
50896
|
];
|
|
50735
50897
|
DEFAULT_TD_TILES = buildDefaultTDTiles();
|
|
50736
|
-
TOWER_SPRITE = `${CDN6}
|
|
50737
|
-
CREEP_SPRITE = `${CDN6}
|
|
50898
|
+
TOWER_SPRITE = `${CDN6}sprite-sheets/guardian-sprite-sheet-se.png`;
|
|
50899
|
+
CREEP_SPRITE = `${CDN6}sprite-sheets/scrapper-sprite-sheet-se.png`;
|
|
50900
|
+
HERO_SPRITE = `${CDN6}sprite-sheets/amir-sprite-sheet-se.png`;
|
|
50738
50901
|
TowerDefenseBoard.displayName = "TowerDefenseBoard";
|
|
50739
50902
|
}
|
|
50740
50903
|
});
|