@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/avl/index.cjs
CHANGED
|
@@ -32130,13 +32130,13 @@ var init_MapView = __esm({
|
|
|
32130
32130
|
shadowSize: [41, 41]
|
|
32131
32131
|
});
|
|
32132
32132
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
32133
|
-
const { useEffect:
|
|
32133
|
+
const { useEffect: useEffect86, useRef: useRef77, useCallback: useCallback125, useState: useState121 } = React90__namespace.default;
|
|
32134
32134
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
32135
32135
|
const { useEventBus: useEventBus4 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
32136
32136
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
32137
32137
|
const map = useMap();
|
|
32138
32138
|
const prevRef = useRef77({ centerLat, centerLng, zoom });
|
|
32139
|
-
|
|
32139
|
+
useEffect86(() => {
|
|
32140
32140
|
const prev = prevRef.current;
|
|
32141
32141
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
32142
32142
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -32147,7 +32147,7 @@ var init_MapView = __esm({
|
|
|
32147
32147
|
}
|
|
32148
32148
|
function MapClickHandler({ onMapClick }) {
|
|
32149
32149
|
const map = useMap();
|
|
32150
|
-
|
|
32150
|
+
useEffect86(() => {
|
|
32151
32151
|
if (!onMapClick) return;
|
|
32152
32152
|
const handler = (e) => {
|
|
32153
32153
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -40199,6 +40199,9 @@ var init_GraphCanvas = __esm({
|
|
|
40199
40199
|
actions,
|
|
40200
40200
|
onNodeClick,
|
|
40201
40201
|
nodeClickEvent,
|
|
40202
|
+
selectedNodeId,
|
|
40203
|
+
repulsion = 800,
|
|
40204
|
+
linkDistance = 100,
|
|
40202
40205
|
layout = "force",
|
|
40203
40206
|
entity,
|
|
40204
40207
|
isLoading = false,
|
|
@@ -40214,6 +40217,35 @@ var init_GraphCanvas = __esm({
|
|
|
40214
40217
|
const [hoveredNode, setHoveredNode] = React90.useState(null);
|
|
40215
40218
|
const nodesRef = React90.useRef([]);
|
|
40216
40219
|
const [, forceUpdate] = React90.useState(0);
|
|
40220
|
+
const interactionRef = React90.useRef({
|
|
40221
|
+
mode: "none",
|
|
40222
|
+
dragNodeId: null,
|
|
40223
|
+
startMouse: { x: 0, y: 0 },
|
|
40224
|
+
startOffset: { x: 0, y: 0 },
|
|
40225
|
+
downPos: { x: 0, y: 0 }
|
|
40226
|
+
});
|
|
40227
|
+
const toCoords = React90.useCallback(
|
|
40228
|
+
(e) => {
|
|
40229
|
+
const canvas = canvasRef.current;
|
|
40230
|
+
if (!canvas) return null;
|
|
40231
|
+
const rect = canvas.getBoundingClientRect();
|
|
40232
|
+
const screenX = e.clientX - rect.left;
|
|
40233
|
+
const screenY = e.clientY - rect.top;
|
|
40234
|
+
return {
|
|
40235
|
+
screenX,
|
|
40236
|
+
screenY,
|
|
40237
|
+
graphX: (screenX - offset.x) / zoom,
|
|
40238
|
+
graphY: (screenY - offset.y) / zoom
|
|
40239
|
+
};
|
|
40240
|
+
},
|
|
40241
|
+
[offset, zoom]
|
|
40242
|
+
);
|
|
40243
|
+
const nodeAt = React90.useCallback((graphX, graphY) => {
|
|
40244
|
+
return nodesRef.current.find((n) => {
|
|
40245
|
+
const dist = Math.sqrt((n.x - graphX) ** 2 + (n.y - graphY) ** 2);
|
|
40246
|
+
return dist < (n.size || 8) + 4;
|
|
40247
|
+
});
|
|
40248
|
+
}, []);
|
|
40217
40249
|
const handleAction = React90.useCallback(
|
|
40218
40250
|
(action) => {
|
|
40219
40251
|
if (action.event) {
|
|
@@ -40279,7 +40311,7 @@ var init_GraphCanvas = __esm({
|
|
|
40279
40311
|
const dx = nodes[j].x - nodes[i].x;
|
|
40280
40312
|
const dy = nodes[j].y - nodes[i].y;
|
|
40281
40313
|
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
40282
|
-
const force =
|
|
40314
|
+
const force = repulsion / (dist * dist);
|
|
40283
40315
|
const fx = dx / dist * force;
|
|
40284
40316
|
const fy = dy / dist * force;
|
|
40285
40317
|
nodes[i].fx -= fx;
|
|
@@ -40295,7 +40327,7 @@ var init_GraphCanvas = __esm({
|
|
|
40295
40327
|
const dx = target.x - source.x;
|
|
40296
40328
|
const dy = target.y - source.y;
|
|
40297
40329
|
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
40298
|
-
const force = (dist -
|
|
40330
|
+
const force = (dist - linkDistance) * 0.05;
|
|
40299
40331
|
const fx = dx / dist * force;
|
|
40300
40332
|
const fy = dy / dist * force;
|
|
40301
40333
|
source.fx += fx;
|
|
@@ -40329,7 +40361,7 @@ var init_GraphCanvas = __esm({
|
|
|
40329
40361
|
return () => {
|
|
40330
40362
|
cancelAnimationFrame(animRef.current);
|
|
40331
40363
|
};
|
|
40332
|
-
}, [propNodes, propEdges, layout]);
|
|
40364
|
+
}, [propNodes, propEdges, layout, repulsion, linkDistance]);
|
|
40333
40365
|
React90.useEffect(() => {
|
|
40334
40366
|
const canvas = canvasRef.current;
|
|
40335
40367
|
if (!canvas) return;
|
|
@@ -40365,18 +40397,25 @@ var init_GraphCanvas = __esm({
|
|
|
40365
40397
|
const size = node.size || 8;
|
|
40366
40398
|
const color = node.color || getGroupColor(node.group, groups);
|
|
40367
40399
|
const isHovered = hoveredNode === node.id;
|
|
40400
|
+
const isSelected = selectedNodeId !== void 0 && node.id === selectedNodeId;
|
|
40401
|
+
const radius = isSelected ? size + 4 : isHovered ? size + 2 : size;
|
|
40368
40402
|
ctx.beginPath();
|
|
40369
|
-
ctx.arc(node.x, node.y,
|
|
40403
|
+
ctx.arc(node.x, node.y, radius, 0, Math.PI * 2);
|
|
40370
40404
|
ctx.fillStyle = color;
|
|
40371
40405
|
ctx.fill();
|
|
40372
|
-
|
|
40373
|
-
|
|
40406
|
+
if (isSelected) {
|
|
40407
|
+
ctx.strokeStyle = "var(--color-accent)";
|
|
40408
|
+
ctx.lineWidth = 3;
|
|
40409
|
+
} else {
|
|
40410
|
+
ctx.strokeStyle = isHovered ? "#ffffff" : "#00000020";
|
|
40411
|
+
ctx.lineWidth = isHovered ? 2 : 1;
|
|
40412
|
+
}
|
|
40374
40413
|
ctx.stroke();
|
|
40375
40414
|
if (showLabels && node.label) {
|
|
40376
40415
|
ctx.fillStyle = "#666666";
|
|
40377
|
-
ctx.font = `${isHovered ? "bold " : ""}10px system-ui`;
|
|
40416
|
+
ctx.font = `${isSelected || isHovered ? "bold " : ""}10px system-ui`;
|
|
40378
40417
|
ctx.textAlign = "center";
|
|
40379
|
-
ctx.fillText(node.label, node.x, node.y +
|
|
40418
|
+
ctx.fillText(node.label, node.x, node.y + radius + 12);
|
|
40380
40419
|
}
|
|
40381
40420
|
}
|
|
40382
40421
|
ctx.restore();
|
|
@@ -40387,6 +40426,97 @@ var init_GraphCanvas = __esm({
|
|
|
40387
40426
|
setZoom(1);
|
|
40388
40427
|
setOffset({ x: 0, y: 0 });
|
|
40389
40428
|
}, []);
|
|
40429
|
+
const handleWheel = React90.useCallback(
|
|
40430
|
+
(e) => {
|
|
40431
|
+
if (!interactive) return;
|
|
40432
|
+
e.preventDefault();
|
|
40433
|
+
const coords = toCoords(e);
|
|
40434
|
+
if (!coords) return;
|
|
40435
|
+
const oldZoom = zoom;
|
|
40436
|
+
const factor = e.deltaY < 0 ? 1.1 : 1 / 1.1;
|
|
40437
|
+
const newZoom = Math.max(0.3, Math.min(3, oldZoom * factor));
|
|
40438
|
+
if (newZoom === oldZoom) return;
|
|
40439
|
+
setOffset((o) => ({
|
|
40440
|
+
x: coords.screenX - (coords.screenX - o.x) * (newZoom / oldZoom),
|
|
40441
|
+
y: coords.screenY - (coords.screenY - o.y) * (newZoom / oldZoom)
|
|
40442
|
+
}));
|
|
40443
|
+
setZoom(newZoom);
|
|
40444
|
+
},
|
|
40445
|
+
[interactive, toCoords, zoom]
|
|
40446
|
+
);
|
|
40447
|
+
const handleMouseDown = React90.useCallback(
|
|
40448
|
+
(e) => {
|
|
40449
|
+
const coords = toCoords(e);
|
|
40450
|
+
if (!coords) return;
|
|
40451
|
+
const node = nodeAt(coords.graphX, coords.graphY);
|
|
40452
|
+
const state = interactionRef.current;
|
|
40453
|
+
state.downPos = { x: e.clientX, y: e.clientY };
|
|
40454
|
+
state.startMouse = { x: e.clientX, y: e.clientY };
|
|
40455
|
+
state.startOffset = { ...offset };
|
|
40456
|
+
if (draggable && node) {
|
|
40457
|
+
state.mode = "dragging";
|
|
40458
|
+
state.dragNodeId = node.id;
|
|
40459
|
+
} else if (interactive) {
|
|
40460
|
+
state.mode = "panning";
|
|
40461
|
+
state.dragNodeId = null;
|
|
40462
|
+
} else {
|
|
40463
|
+
state.mode = "none";
|
|
40464
|
+
state.dragNodeId = null;
|
|
40465
|
+
}
|
|
40466
|
+
},
|
|
40467
|
+
[toCoords, nodeAt, draggable, interactive, offset]
|
|
40468
|
+
);
|
|
40469
|
+
const handleMouseMove = React90.useCallback(
|
|
40470
|
+
(e) => {
|
|
40471
|
+
const state = interactionRef.current;
|
|
40472
|
+
if (state.mode === "panning") {
|
|
40473
|
+
const dx = e.clientX - state.startMouse.x;
|
|
40474
|
+
const dy = e.clientY - state.startMouse.y;
|
|
40475
|
+
setOffset({ x: state.startOffset.x + dx, y: state.startOffset.y + dy });
|
|
40476
|
+
return;
|
|
40477
|
+
}
|
|
40478
|
+
if (state.mode === "dragging" && state.dragNodeId) {
|
|
40479
|
+
const coords2 = toCoords(e);
|
|
40480
|
+
if (!coords2) return;
|
|
40481
|
+
const node2 = nodesRef.current.find((n) => n.id === state.dragNodeId);
|
|
40482
|
+
if (node2) {
|
|
40483
|
+
node2.x = coords2.graphX;
|
|
40484
|
+
node2.y = coords2.graphY;
|
|
40485
|
+
node2.vx = 0;
|
|
40486
|
+
node2.vy = 0;
|
|
40487
|
+
forceUpdate((n) => n + 1);
|
|
40488
|
+
}
|
|
40489
|
+
return;
|
|
40490
|
+
}
|
|
40491
|
+
const coords = toCoords(e);
|
|
40492
|
+
if (!coords) return;
|
|
40493
|
+
const node = nodeAt(coords.graphX, coords.graphY);
|
|
40494
|
+
setHoveredNode(node?.id ?? null);
|
|
40495
|
+
},
|
|
40496
|
+
[toCoords, nodeAt]
|
|
40497
|
+
);
|
|
40498
|
+
const handleMouseUp = React90.useCallback(
|
|
40499
|
+
(e) => {
|
|
40500
|
+
const state = interactionRef.current;
|
|
40501
|
+
const moved = Math.abs(e.clientX - state.downPos.x) + Math.abs(e.clientY - state.downPos.y);
|
|
40502
|
+
state.mode = "none";
|
|
40503
|
+
state.dragNodeId = null;
|
|
40504
|
+
if (moved < 4) {
|
|
40505
|
+
const coords = toCoords(e);
|
|
40506
|
+
if (!coords) return;
|
|
40507
|
+
const node = nodeAt(coords.graphX, coords.graphY);
|
|
40508
|
+
if (node) {
|
|
40509
|
+
handleNodeClick(node);
|
|
40510
|
+
}
|
|
40511
|
+
}
|
|
40512
|
+
},
|
|
40513
|
+
[toCoords, nodeAt, handleNodeClick]
|
|
40514
|
+
);
|
|
40515
|
+
const handleMouseLeave = React90.useCallback(() => {
|
|
40516
|
+
interactionRef.current.mode = "none";
|
|
40517
|
+
interactionRef.current.dragNodeId = null;
|
|
40518
|
+
setHoveredNode(null);
|
|
40519
|
+
}, []);
|
|
40390
40520
|
if (isLoading) {
|
|
40391
40521
|
return /* @__PURE__ */ jsxRuntime.jsx(LoadingState, { message: t("common.loading"), className });
|
|
40392
40522
|
}
|
|
@@ -40448,20 +40578,11 @@ var init_GraphCanvas = __esm({
|
|
|
40448
40578
|
height,
|
|
40449
40579
|
className: "w-full cursor-grab active:cursor-grabbing",
|
|
40450
40580
|
style: { height },
|
|
40451
|
-
|
|
40452
|
-
|
|
40453
|
-
|
|
40454
|
-
|
|
40455
|
-
|
|
40456
|
-
const y = (e.clientY - rect.top - offset.y) / zoom;
|
|
40457
|
-
const clickedNode = nodesRef.current.find((n) => {
|
|
40458
|
-
const dist = Math.sqrt((n.x - x) ** 2 + (n.y - y) ** 2);
|
|
40459
|
-
return dist < (n.size || 8) + 4;
|
|
40460
|
-
});
|
|
40461
|
-
if (clickedNode) {
|
|
40462
|
-
handleNodeClick(clickedNode);
|
|
40463
|
-
}
|
|
40464
|
-
}
|
|
40581
|
+
onWheel: handleWheel,
|
|
40582
|
+
onMouseDown: handleMouseDown,
|
|
40583
|
+
onMouseMove: handleMouseMove,
|
|
40584
|
+
onMouseUp: handleMouseUp,
|
|
40585
|
+
onMouseLeave: handleMouseLeave
|
|
40465
40586
|
}
|
|
40466
40587
|
) }),
|
|
40467
40588
|
groups.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "md", className: "px-4 py-2 border-t border-border", wrap: true, children: groups.map((group, idx) => /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
@@ -51557,12 +51678,25 @@ function pathToFeatures(path) {
|
|
|
51557
51678
|
sprite: `${CDN6}world-map/road_straight.png`
|
|
51558
51679
|
}));
|
|
51559
51680
|
}
|
|
51681
|
+
function heroToUnit(hero) {
|
|
51682
|
+
return {
|
|
51683
|
+
id: hero.id,
|
|
51684
|
+
position: { x: hero.x, y: hero.y },
|
|
51685
|
+
name: "Hero",
|
|
51686
|
+
team: "player",
|
|
51687
|
+
sprite: HERO_SPRITE,
|
|
51688
|
+
unitType: "amir",
|
|
51689
|
+
health: 1,
|
|
51690
|
+
maxHealth: 1
|
|
51691
|
+
};
|
|
51692
|
+
}
|
|
51560
51693
|
function TowerDefenseBoard({
|
|
51561
51694
|
entity,
|
|
51562
51695
|
tiles: propTiles,
|
|
51563
51696
|
path: propPath,
|
|
51564
51697
|
towers: propTowers,
|
|
51565
51698
|
creeps: propCreeps,
|
|
51699
|
+
hero: propHero,
|
|
51566
51700
|
gold: propGold,
|
|
51567
51701
|
lives: propLives,
|
|
51568
51702
|
wave: propWave,
|
|
@@ -51578,6 +51712,7 @@ function TowerDefenseBoard({
|
|
|
51578
51712
|
startWaveEvent,
|
|
51579
51713
|
playAgainEvent,
|
|
51580
51714
|
gameEndEvent,
|
|
51715
|
+
moveHeroEvent,
|
|
51581
51716
|
className
|
|
51582
51717
|
}) {
|
|
51583
51718
|
const board = boardEntity(entity) ?? {};
|
|
@@ -51589,6 +51724,7 @@ function TowerDefenseBoard({
|
|
|
51589
51724
|
const path = rawPath.length > 0 ? rawPath : DEFAULT_TD_PATH;
|
|
51590
51725
|
const towers = propTowers ?? rows(board.towers);
|
|
51591
51726
|
const creeps = propCreeps ?? rows(board.creeps);
|
|
51727
|
+
const hero = propHero ?? { id: "hero", x: 8, y: 8 };
|
|
51592
51728
|
const gold = propGold ?? num(board.gold, 100);
|
|
51593
51729
|
const lives = propLives ?? num(board.lives, 20);
|
|
51594
51730
|
const wave = propWave ?? num(board.wave, 1);
|
|
@@ -51606,6 +51742,31 @@ function TowerDefenseBoard({
|
|
|
51606
51742
|
if (result === "none") {
|
|
51607
51743
|
emittedGameEnd.current = false;
|
|
51608
51744
|
}
|
|
51745
|
+
const moveHeroEventRef = React90.useRef(moveHeroEvent);
|
|
51746
|
+
moveHeroEventRef.current = moveHeroEvent;
|
|
51747
|
+
const resultRef = React90.useRef(result);
|
|
51748
|
+
resultRef.current = result;
|
|
51749
|
+
React90.useEffect(() => {
|
|
51750
|
+
function onKeyDown(e) {
|
|
51751
|
+
const evt = moveHeroEventRef.current;
|
|
51752
|
+
if (!evt || resultRef.current !== "none") return;
|
|
51753
|
+
let dx = 0;
|
|
51754
|
+
let dy = 0;
|
|
51755
|
+
if (e.key === "ArrowUp") {
|
|
51756
|
+
dy = -1;
|
|
51757
|
+
} else if (e.key === "ArrowDown") {
|
|
51758
|
+
dy = 1;
|
|
51759
|
+
} else if (e.key === "ArrowLeft") {
|
|
51760
|
+
dx = -1;
|
|
51761
|
+
} else if (e.key === "ArrowRight") {
|
|
51762
|
+
dx = 1;
|
|
51763
|
+
} else return;
|
|
51764
|
+
e.preventDefault();
|
|
51765
|
+
eventBus.emit(`UI:${evt}`, { dx, dy });
|
|
51766
|
+
}
|
|
51767
|
+
window.addEventListener("keydown", onKeyDown);
|
|
51768
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
51769
|
+
}, [eventBus]);
|
|
51609
51770
|
const towerPositions = React90.useMemo(() => new Set(towers.map((t2) => `${t2.x},${t2.y}`)), [towers]);
|
|
51610
51771
|
const pathPositions = React90.useMemo(() => new Set(path.map((p2) => `${p2.x},${p2.y}`)), [path]);
|
|
51611
51772
|
const validMoves = React90.useMemo(() => {
|
|
@@ -51617,7 +51778,8 @@ function TowerDefenseBoard({
|
|
|
51617
51778
|
const isoTiles = React90.useMemo(() => tilesToIso(tiles), [tiles]);
|
|
51618
51779
|
const towerUnits = React90.useMemo(() => towersToUnits(towers), [towers]);
|
|
51619
51780
|
const creepUnits = React90.useMemo(() => creepsToUnits(creeps), [creeps]);
|
|
51620
|
-
const
|
|
51781
|
+
const heroUnit = React90.useMemo(() => heroToUnit(hero), [hero]);
|
|
51782
|
+
const isoUnits = React90.useMemo(() => [...towerUnits, ...creepUnits, heroUnit], [towerUnits, creepUnits, heroUnit]);
|
|
51621
51783
|
const pathFeatures = React90.useMemo(() => pathToFeatures(path), [path]);
|
|
51622
51784
|
const handleTileClick = React90.useCallback((x, y) => {
|
|
51623
51785
|
if (result !== "none") return;
|
|
@@ -51716,7 +51878,7 @@ function TowerDefenseBoard({
|
|
|
51716
51878
|
] }) })
|
|
51717
51879
|
] });
|
|
51718
51880
|
}
|
|
51719
|
-
var CDN6, TD_GRID_W, TD_GRID_H, TERRAIN_SPRITES, DEFAULT_TD_PATH, DEFAULT_TD_TILES, TOWER_SPRITE, CREEP_SPRITE;
|
|
51881
|
+
var CDN6, TD_GRID_W, TD_GRID_H, TERRAIN_SPRITES, DEFAULT_TD_PATH, DEFAULT_TD_TILES, TOWER_SPRITE, CREEP_SPRITE, HERO_SPRITE;
|
|
51720
51882
|
var init_TowerDefenseBoard = __esm({
|
|
51721
51883
|
"components/game/organisms/TowerDefenseBoard.tsx"() {
|
|
51722
51884
|
"use client";
|
|
@@ -51790,8 +51952,9 @@ var init_TowerDefenseBoard = __esm({
|
|
|
51790
51952
|
{ x: 13, y: 15 }
|
|
51791
51953
|
];
|
|
51792
51954
|
DEFAULT_TD_TILES = buildDefaultTDTiles();
|
|
51793
|
-
TOWER_SPRITE = `${CDN6}
|
|
51794
|
-
CREEP_SPRITE = `${CDN6}
|
|
51955
|
+
TOWER_SPRITE = `${CDN6}sprite-sheets/guardian-sprite-sheet-se.png`;
|
|
51956
|
+
CREEP_SPRITE = `${CDN6}sprite-sheets/scrapper-sprite-sheet-se.png`;
|
|
51957
|
+
HERO_SPRITE = `${CDN6}sprite-sheets/amir-sprite-sheet-se.png`;
|
|
51795
51958
|
TowerDefenseBoard.displayName = "TowerDefenseBoard";
|
|
51796
51959
|
}
|
|
51797
51960
|
});
|