@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
package/dist/components/index.js
CHANGED
|
@@ -29895,13 +29895,13 @@ var init_MapView = __esm({
|
|
|
29895
29895
|
shadowSize: [41, 41]
|
|
29896
29896
|
});
|
|
29897
29897
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
29898
|
-
const { useEffect:
|
|
29898
|
+
const { useEffect: useEffect81, useRef: useRef78, useCallback: useCallback120, useState: useState110 } = React76__default;
|
|
29899
29899
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
29900
29900
|
const { useEventBus: useEventBus3 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
29901
29901
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
29902
29902
|
const map = useMap();
|
|
29903
29903
|
const prevRef = useRef78({ centerLat, centerLng, zoom });
|
|
29904
|
-
|
|
29904
|
+
useEffect81(() => {
|
|
29905
29905
|
const prev = prevRef.current;
|
|
29906
29906
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
29907
29907
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -29912,7 +29912,7 @@ var init_MapView = __esm({
|
|
|
29912
29912
|
}
|
|
29913
29913
|
function MapClickHandler({ onMapClick }) {
|
|
29914
29914
|
const map = useMap();
|
|
29915
|
-
|
|
29915
|
+
useEffect81(() => {
|
|
29916
29916
|
if (!onMapClick) return;
|
|
29917
29917
|
const handler = (e) => {
|
|
29918
29918
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -38373,6 +38373,9 @@ var init_GraphCanvas = __esm({
|
|
|
38373
38373
|
actions,
|
|
38374
38374
|
onNodeClick,
|
|
38375
38375
|
nodeClickEvent,
|
|
38376
|
+
selectedNodeId,
|
|
38377
|
+
repulsion = 800,
|
|
38378
|
+
linkDistance = 100,
|
|
38376
38379
|
layout = "force",
|
|
38377
38380
|
entity,
|
|
38378
38381
|
isLoading = false,
|
|
@@ -38388,6 +38391,35 @@ var init_GraphCanvas = __esm({
|
|
|
38388
38391
|
const [hoveredNode, setHoveredNode] = useState(null);
|
|
38389
38392
|
const nodesRef = useRef([]);
|
|
38390
38393
|
const [, forceUpdate] = useState(0);
|
|
38394
|
+
const interactionRef = useRef({
|
|
38395
|
+
mode: "none",
|
|
38396
|
+
dragNodeId: null,
|
|
38397
|
+
startMouse: { x: 0, y: 0 },
|
|
38398
|
+
startOffset: { x: 0, y: 0 },
|
|
38399
|
+
downPos: { x: 0, y: 0 }
|
|
38400
|
+
});
|
|
38401
|
+
const toCoords = useCallback(
|
|
38402
|
+
(e) => {
|
|
38403
|
+
const canvas = canvasRef.current;
|
|
38404
|
+
if (!canvas) return null;
|
|
38405
|
+
const rect = canvas.getBoundingClientRect();
|
|
38406
|
+
const screenX = e.clientX - rect.left;
|
|
38407
|
+
const screenY = e.clientY - rect.top;
|
|
38408
|
+
return {
|
|
38409
|
+
screenX,
|
|
38410
|
+
screenY,
|
|
38411
|
+
graphX: (screenX - offset.x) / zoom,
|
|
38412
|
+
graphY: (screenY - offset.y) / zoom
|
|
38413
|
+
};
|
|
38414
|
+
},
|
|
38415
|
+
[offset, zoom]
|
|
38416
|
+
);
|
|
38417
|
+
const nodeAt = useCallback((graphX, graphY) => {
|
|
38418
|
+
return nodesRef.current.find((n) => {
|
|
38419
|
+
const dist = Math.sqrt((n.x - graphX) ** 2 + (n.y - graphY) ** 2);
|
|
38420
|
+
return dist < (n.size || 8) + 4;
|
|
38421
|
+
});
|
|
38422
|
+
}, []);
|
|
38391
38423
|
const handleAction = useCallback(
|
|
38392
38424
|
(action) => {
|
|
38393
38425
|
if (action.event) {
|
|
@@ -38453,7 +38485,7 @@ var init_GraphCanvas = __esm({
|
|
|
38453
38485
|
const dx = nodes[j].x - nodes[i].x;
|
|
38454
38486
|
const dy = nodes[j].y - nodes[i].y;
|
|
38455
38487
|
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
38456
|
-
const force =
|
|
38488
|
+
const force = repulsion / (dist * dist);
|
|
38457
38489
|
const fx = dx / dist * force;
|
|
38458
38490
|
const fy = dy / dist * force;
|
|
38459
38491
|
nodes[i].fx -= fx;
|
|
@@ -38469,7 +38501,7 @@ var init_GraphCanvas = __esm({
|
|
|
38469
38501
|
const dx = target.x - source.x;
|
|
38470
38502
|
const dy = target.y - source.y;
|
|
38471
38503
|
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
38472
|
-
const force = (dist -
|
|
38504
|
+
const force = (dist - linkDistance) * 0.05;
|
|
38473
38505
|
const fx = dx / dist * force;
|
|
38474
38506
|
const fy = dy / dist * force;
|
|
38475
38507
|
source.fx += fx;
|
|
@@ -38503,7 +38535,7 @@ var init_GraphCanvas = __esm({
|
|
|
38503
38535
|
return () => {
|
|
38504
38536
|
cancelAnimationFrame(animRef.current);
|
|
38505
38537
|
};
|
|
38506
|
-
}, [propNodes, propEdges, layout]);
|
|
38538
|
+
}, [propNodes, propEdges, layout, repulsion, linkDistance]);
|
|
38507
38539
|
useEffect(() => {
|
|
38508
38540
|
const canvas = canvasRef.current;
|
|
38509
38541
|
if (!canvas) return;
|
|
@@ -38539,18 +38571,25 @@ var init_GraphCanvas = __esm({
|
|
|
38539
38571
|
const size = node.size || 8;
|
|
38540
38572
|
const color = node.color || getGroupColor(node.group, groups);
|
|
38541
38573
|
const isHovered = hoveredNode === node.id;
|
|
38574
|
+
const isSelected = selectedNodeId !== void 0 && node.id === selectedNodeId;
|
|
38575
|
+
const radius = isSelected ? size + 4 : isHovered ? size + 2 : size;
|
|
38542
38576
|
ctx.beginPath();
|
|
38543
|
-
ctx.arc(node.x, node.y,
|
|
38577
|
+
ctx.arc(node.x, node.y, radius, 0, Math.PI * 2);
|
|
38544
38578
|
ctx.fillStyle = color;
|
|
38545
38579
|
ctx.fill();
|
|
38546
|
-
|
|
38547
|
-
|
|
38580
|
+
if (isSelected) {
|
|
38581
|
+
ctx.strokeStyle = "var(--color-accent)";
|
|
38582
|
+
ctx.lineWidth = 3;
|
|
38583
|
+
} else {
|
|
38584
|
+
ctx.strokeStyle = isHovered ? "#ffffff" : "#00000020";
|
|
38585
|
+
ctx.lineWidth = isHovered ? 2 : 1;
|
|
38586
|
+
}
|
|
38548
38587
|
ctx.stroke();
|
|
38549
38588
|
if (showLabels && node.label) {
|
|
38550
38589
|
ctx.fillStyle = "#666666";
|
|
38551
|
-
ctx.font = `${isHovered ? "bold " : ""}10px system-ui`;
|
|
38590
|
+
ctx.font = `${isSelected || isHovered ? "bold " : ""}10px system-ui`;
|
|
38552
38591
|
ctx.textAlign = "center";
|
|
38553
|
-
ctx.fillText(node.label, node.x, node.y +
|
|
38592
|
+
ctx.fillText(node.label, node.x, node.y + radius + 12);
|
|
38554
38593
|
}
|
|
38555
38594
|
}
|
|
38556
38595
|
ctx.restore();
|
|
@@ -38561,6 +38600,97 @@ var init_GraphCanvas = __esm({
|
|
|
38561
38600
|
setZoom(1);
|
|
38562
38601
|
setOffset({ x: 0, y: 0 });
|
|
38563
38602
|
}, []);
|
|
38603
|
+
const handleWheel = useCallback(
|
|
38604
|
+
(e) => {
|
|
38605
|
+
if (!interactive) return;
|
|
38606
|
+
e.preventDefault();
|
|
38607
|
+
const coords = toCoords(e);
|
|
38608
|
+
if (!coords) return;
|
|
38609
|
+
const oldZoom = zoom;
|
|
38610
|
+
const factor = e.deltaY < 0 ? 1.1 : 1 / 1.1;
|
|
38611
|
+
const newZoom = Math.max(0.3, Math.min(3, oldZoom * factor));
|
|
38612
|
+
if (newZoom === oldZoom) return;
|
|
38613
|
+
setOffset((o) => ({
|
|
38614
|
+
x: coords.screenX - (coords.screenX - o.x) * (newZoom / oldZoom),
|
|
38615
|
+
y: coords.screenY - (coords.screenY - o.y) * (newZoom / oldZoom)
|
|
38616
|
+
}));
|
|
38617
|
+
setZoom(newZoom);
|
|
38618
|
+
},
|
|
38619
|
+
[interactive, toCoords, zoom]
|
|
38620
|
+
);
|
|
38621
|
+
const handleMouseDown = useCallback(
|
|
38622
|
+
(e) => {
|
|
38623
|
+
const coords = toCoords(e);
|
|
38624
|
+
if (!coords) return;
|
|
38625
|
+
const node = nodeAt(coords.graphX, coords.graphY);
|
|
38626
|
+
const state = interactionRef.current;
|
|
38627
|
+
state.downPos = { x: e.clientX, y: e.clientY };
|
|
38628
|
+
state.startMouse = { x: e.clientX, y: e.clientY };
|
|
38629
|
+
state.startOffset = { ...offset };
|
|
38630
|
+
if (draggable && node) {
|
|
38631
|
+
state.mode = "dragging";
|
|
38632
|
+
state.dragNodeId = node.id;
|
|
38633
|
+
} else if (interactive) {
|
|
38634
|
+
state.mode = "panning";
|
|
38635
|
+
state.dragNodeId = null;
|
|
38636
|
+
} else {
|
|
38637
|
+
state.mode = "none";
|
|
38638
|
+
state.dragNodeId = null;
|
|
38639
|
+
}
|
|
38640
|
+
},
|
|
38641
|
+
[toCoords, nodeAt, draggable, interactive, offset]
|
|
38642
|
+
);
|
|
38643
|
+
const handleMouseMove = useCallback(
|
|
38644
|
+
(e) => {
|
|
38645
|
+
const state = interactionRef.current;
|
|
38646
|
+
if (state.mode === "panning") {
|
|
38647
|
+
const dx = e.clientX - state.startMouse.x;
|
|
38648
|
+
const dy = e.clientY - state.startMouse.y;
|
|
38649
|
+
setOffset({ x: state.startOffset.x + dx, y: state.startOffset.y + dy });
|
|
38650
|
+
return;
|
|
38651
|
+
}
|
|
38652
|
+
if (state.mode === "dragging" && state.dragNodeId) {
|
|
38653
|
+
const coords2 = toCoords(e);
|
|
38654
|
+
if (!coords2) return;
|
|
38655
|
+
const node2 = nodesRef.current.find((n) => n.id === state.dragNodeId);
|
|
38656
|
+
if (node2) {
|
|
38657
|
+
node2.x = coords2.graphX;
|
|
38658
|
+
node2.y = coords2.graphY;
|
|
38659
|
+
node2.vx = 0;
|
|
38660
|
+
node2.vy = 0;
|
|
38661
|
+
forceUpdate((n) => n + 1);
|
|
38662
|
+
}
|
|
38663
|
+
return;
|
|
38664
|
+
}
|
|
38665
|
+
const coords = toCoords(e);
|
|
38666
|
+
if (!coords) return;
|
|
38667
|
+
const node = nodeAt(coords.graphX, coords.graphY);
|
|
38668
|
+
setHoveredNode(node?.id ?? null);
|
|
38669
|
+
},
|
|
38670
|
+
[toCoords, nodeAt]
|
|
38671
|
+
);
|
|
38672
|
+
const handleMouseUp = useCallback(
|
|
38673
|
+
(e) => {
|
|
38674
|
+
const state = interactionRef.current;
|
|
38675
|
+
const moved = Math.abs(e.clientX - state.downPos.x) + Math.abs(e.clientY - state.downPos.y);
|
|
38676
|
+
state.mode = "none";
|
|
38677
|
+
state.dragNodeId = null;
|
|
38678
|
+
if (moved < 4) {
|
|
38679
|
+
const coords = toCoords(e);
|
|
38680
|
+
if (!coords) return;
|
|
38681
|
+
const node = nodeAt(coords.graphX, coords.graphY);
|
|
38682
|
+
if (node) {
|
|
38683
|
+
handleNodeClick(node);
|
|
38684
|
+
}
|
|
38685
|
+
}
|
|
38686
|
+
},
|
|
38687
|
+
[toCoords, nodeAt, handleNodeClick]
|
|
38688
|
+
);
|
|
38689
|
+
const handleMouseLeave = useCallback(() => {
|
|
38690
|
+
interactionRef.current.mode = "none";
|
|
38691
|
+
interactionRef.current.dragNodeId = null;
|
|
38692
|
+
setHoveredNode(null);
|
|
38693
|
+
}, []);
|
|
38564
38694
|
if (isLoading) {
|
|
38565
38695
|
return /* @__PURE__ */ jsx(LoadingState, { message: t("common.loading"), className });
|
|
38566
38696
|
}
|
|
@@ -38622,20 +38752,11 @@ var init_GraphCanvas = __esm({
|
|
|
38622
38752
|
height,
|
|
38623
38753
|
className: "w-full cursor-grab active:cursor-grabbing",
|
|
38624
38754
|
style: { height },
|
|
38625
|
-
|
|
38626
|
-
|
|
38627
|
-
|
|
38628
|
-
|
|
38629
|
-
|
|
38630
|
-
const y = (e.clientY - rect.top - offset.y) / zoom;
|
|
38631
|
-
const clickedNode = nodesRef.current.find((n) => {
|
|
38632
|
-
const dist = Math.sqrt((n.x - x) ** 2 + (n.y - y) ** 2);
|
|
38633
|
-
return dist < (n.size || 8) + 4;
|
|
38634
|
-
});
|
|
38635
|
-
if (clickedNode) {
|
|
38636
|
-
handleNodeClick(clickedNode);
|
|
38637
|
-
}
|
|
38638
|
-
}
|
|
38755
|
+
onWheel: handleWheel,
|
|
38756
|
+
onMouseDown: handleMouseDown,
|
|
38757
|
+
onMouseMove: handleMouseMove,
|
|
38758
|
+
onMouseUp: handleMouseUp,
|
|
38759
|
+
onMouseLeave: handleMouseLeave
|
|
38639
38760
|
}
|
|
38640
38761
|
) }),
|
|
38641
38762
|
groups.length > 1 && /* @__PURE__ */ jsx(HStack, { gap: "md", className: "px-4 py-2 border-t border-border", wrap: true, children: groups.map((group, idx) => /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
@@ -50454,12 +50575,25 @@ function pathToFeatures(path) {
|
|
|
50454
50575
|
sprite: `${CDN6}world-map/road_straight.png`
|
|
50455
50576
|
}));
|
|
50456
50577
|
}
|
|
50578
|
+
function heroToUnit(hero) {
|
|
50579
|
+
return {
|
|
50580
|
+
id: hero.id,
|
|
50581
|
+
position: { x: hero.x, y: hero.y },
|
|
50582
|
+
name: "Hero",
|
|
50583
|
+
team: "player",
|
|
50584
|
+
sprite: HERO_SPRITE,
|
|
50585
|
+
unitType: "amir",
|
|
50586
|
+
health: 1,
|
|
50587
|
+
maxHealth: 1
|
|
50588
|
+
};
|
|
50589
|
+
}
|
|
50457
50590
|
function TowerDefenseBoard({
|
|
50458
50591
|
entity,
|
|
50459
50592
|
tiles: propTiles,
|
|
50460
50593
|
path: propPath,
|
|
50461
50594
|
towers: propTowers,
|
|
50462
50595
|
creeps: propCreeps,
|
|
50596
|
+
hero: propHero,
|
|
50463
50597
|
gold: propGold,
|
|
50464
50598
|
lives: propLives,
|
|
50465
50599
|
wave: propWave,
|
|
@@ -50475,6 +50609,7 @@ function TowerDefenseBoard({
|
|
|
50475
50609
|
startWaveEvent,
|
|
50476
50610
|
playAgainEvent,
|
|
50477
50611
|
gameEndEvent,
|
|
50612
|
+
moveHeroEvent,
|
|
50478
50613
|
className
|
|
50479
50614
|
}) {
|
|
50480
50615
|
const board = boardEntity(entity) ?? {};
|
|
@@ -50486,6 +50621,7 @@ function TowerDefenseBoard({
|
|
|
50486
50621
|
const path = rawPath.length > 0 ? rawPath : DEFAULT_TD_PATH;
|
|
50487
50622
|
const towers = propTowers ?? rows(board.towers);
|
|
50488
50623
|
const creeps = propCreeps ?? rows(board.creeps);
|
|
50624
|
+
const hero = propHero ?? { id: "hero", x: 8, y: 8 };
|
|
50489
50625
|
const gold = propGold ?? num(board.gold, 100);
|
|
50490
50626
|
const lives = propLives ?? num(board.lives, 20);
|
|
50491
50627
|
const wave = propWave ?? num(board.wave, 1);
|
|
@@ -50503,6 +50639,31 @@ function TowerDefenseBoard({
|
|
|
50503
50639
|
if (result === "none") {
|
|
50504
50640
|
emittedGameEnd.current = false;
|
|
50505
50641
|
}
|
|
50642
|
+
const moveHeroEventRef = useRef(moveHeroEvent);
|
|
50643
|
+
moveHeroEventRef.current = moveHeroEvent;
|
|
50644
|
+
const resultRef = useRef(result);
|
|
50645
|
+
resultRef.current = result;
|
|
50646
|
+
useEffect(() => {
|
|
50647
|
+
function onKeyDown(e) {
|
|
50648
|
+
const evt = moveHeroEventRef.current;
|
|
50649
|
+
if (!evt || resultRef.current !== "none") return;
|
|
50650
|
+
let dx = 0;
|
|
50651
|
+
let dy = 0;
|
|
50652
|
+
if (e.key === "ArrowUp") {
|
|
50653
|
+
dy = -1;
|
|
50654
|
+
} else if (e.key === "ArrowDown") {
|
|
50655
|
+
dy = 1;
|
|
50656
|
+
} else if (e.key === "ArrowLeft") {
|
|
50657
|
+
dx = -1;
|
|
50658
|
+
} else if (e.key === "ArrowRight") {
|
|
50659
|
+
dx = 1;
|
|
50660
|
+
} else return;
|
|
50661
|
+
e.preventDefault();
|
|
50662
|
+
eventBus.emit(`UI:${evt}`, { dx, dy });
|
|
50663
|
+
}
|
|
50664
|
+
window.addEventListener("keydown", onKeyDown);
|
|
50665
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
50666
|
+
}, [eventBus]);
|
|
50506
50667
|
const towerPositions = useMemo(() => new Set(towers.map((t2) => `${t2.x},${t2.y}`)), [towers]);
|
|
50507
50668
|
const pathPositions = useMemo(() => new Set(path.map((p2) => `${p2.x},${p2.y}`)), [path]);
|
|
50508
50669
|
const validMoves = useMemo(() => {
|
|
@@ -50514,7 +50675,8 @@ function TowerDefenseBoard({
|
|
|
50514
50675
|
const isoTiles = useMemo(() => tilesToIso(tiles), [tiles]);
|
|
50515
50676
|
const towerUnits = useMemo(() => towersToUnits(towers), [towers]);
|
|
50516
50677
|
const creepUnits = useMemo(() => creepsToUnits(creeps), [creeps]);
|
|
50517
|
-
const
|
|
50678
|
+
const heroUnit = useMemo(() => heroToUnit(hero), [hero]);
|
|
50679
|
+
const isoUnits = useMemo(() => [...towerUnits, ...creepUnits, heroUnit], [towerUnits, creepUnits, heroUnit]);
|
|
50518
50680
|
const pathFeatures = useMemo(() => pathToFeatures(path), [path]);
|
|
50519
50681
|
const handleTileClick = useCallback((x, y) => {
|
|
50520
50682
|
if (result !== "none") return;
|
|
@@ -50613,7 +50775,7 @@ function TowerDefenseBoard({
|
|
|
50613
50775
|
] }) })
|
|
50614
50776
|
] });
|
|
50615
50777
|
}
|
|
50616
|
-
var CDN6, TD_GRID_W, TD_GRID_H, TERRAIN_SPRITES, DEFAULT_TD_PATH, DEFAULT_TD_TILES, TOWER_SPRITE, CREEP_SPRITE;
|
|
50778
|
+
var CDN6, TD_GRID_W, TD_GRID_H, TERRAIN_SPRITES, DEFAULT_TD_PATH, DEFAULT_TD_TILES, TOWER_SPRITE, CREEP_SPRITE, HERO_SPRITE;
|
|
50617
50779
|
var init_TowerDefenseBoard = __esm({
|
|
50618
50780
|
"components/game/organisms/TowerDefenseBoard.tsx"() {
|
|
50619
50781
|
"use client";
|
|
@@ -50687,8 +50849,9 @@ var init_TowerDefenseBoard = __esm({
|
|
|
50687
50849
|
{ x: 13, y: 15 }
|
|
50688
50850
|
];
|
|
50689
50851
|
DEFAULT_TD_TILES = buildDefaultTDTiles();
|
|
50690
|
-
TOWER_SPRITE = `${CDN6}
|
|
50691
|
-
CREEP_SPRITE = `${CDN6}
|
|
50852
|
+
TOWER_SPRITE = `${CDN6}sprite-sheets/guardian-sprite-sheet-se.png`;
|
|
50853
|
+
CREEP_SPRITE = `${CDN6}sprite-sheets/scrapper-sprite-sheet-se.png`;
|
|
50854
|
+
HERO_SPRITE = `${CDN6}sprite-sheets/amir-sprite-sheet-se.png`;
|
|
50692
50855
|
TowerDefenseBoard.displayName = "TowerDefenseBoard";
|
|
50693
50856
|
}
|
|
50694
50857
|
});
|