@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/providers/index.cjs
CHANGED
|
@@ -29522,13 +29522,13 @@ var init_MapView = __esm({
|
|
|
29522
29522
|
shadowSize: [41, 41]
|
|
29523
29523
|
});
|
|
29524
29524
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
29525
|
-
const { useEffect:
|
|
29525
|
+
const { useEffect: useEffect80, useRef: useRef75, useCallback: useCallback118, useState: useState109 } = React82__namespace.default;
|
|
29526
29526
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
29527
29527
|
const { useEventBus: useEventBus3 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
29528
29528
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
29529
29529
|
const map = useMap();
|
|
29530
29530
|
const prevRef = useRef75({ centerLat, centerLng, zoom });
|
|
29531
|
-
|
|
29531
|
+
useEffect80(() => {
|
|
29532
29532
|
const prev = prevRef.current;
|
|
29533
29533
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
29534
29534
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -29539,7 +29539,7 @@ var init_MapView = __esm({
|
|
|
29539
29539
|
}
|
|
29540
29540
|
function MapClickHandler({ onMapClick }) {
|
|
29541
29541
|
const map = useMap();
|
|
29542
|
-
|
|
29542
|
+
useEffect80(() => {
|
|
29543
29543
|
if (!onMapClick) return;
|
|
29544
29544
|
const handler = (e) => {
|
|
29545
29545
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -38000,6 +38000,9 @@ var init_GraphCanvas = __esm({
|
|
|
38000
38000
|
actions,
|
|
38001
38001
|
onNodeClick,
|
|
38002
38002
|
nodeClickEvent,
|
|
38003
|
+
selectedNodeId,
|
|
38004
|
+
repulsion = 800,
|
|
38005
|
+
linkDistance = 100,
|
|
38003
38006
|
layout = "force",
|
|
38004
38007
|
entity,
|
|
38005
38008
|
isLoading = false,
|
|
@@ -38015,6 +38018,35 @@ var init_GraphCanvas = __esm({
|
|
|
38015
38018
|
const [hoveredNode, setHoveredNode] = React82.useState(null);
|
|
38016
38019
|
const nodesRef = React82.useRef([]);
|
|
38017
38020
|
const [, forceUpdate] = React82.useState(0);
|
|
38021
|
+
const interactionRef = React82.useRef({
|
|
38022
|
+
mode: "none",
|
|
38023
|
+
dragNodeId: null,
|
|
38024
|
+
startMouse: { x: 0, y: 0 },
|
|
38025
|
+
startOffset: { x: 0, y: 0 },
|
|
38026
|
+
downPos: { x: 0, y: 0 }
|
|
38027
|
+
});
|
|
38028
|
+
const toCoords = React82.useCallback(
|
|
38029
|
+
(e) => {
|
|
38030
|
+
const canvas = canvasRef.current;
|
|
38031
|
+
if (!canvas) return null;
|
|
38032
|
+
const rect = canvas.getBoundingClientRect();
|
|
38033
|
+
const screenX = e.clientX - rect.left;
|
|
38034
|
+
const screenY = e.clientY - rect.top;
|
|
38035
|
+
return {
|
|
38036
|
+
screenX,
|
|
38037
|
+
screenY,
|
|
38038
|
+
graphX: (screenX - offset.x) / zoom,
|
|
38039
|
+
graphY: (screenY - offset.y) / zoom
|
|
38040
|
+
};
|
|
38041
|
+
},
|
|
38042
|
+
[offset, zoom]
|
|
38043
|
+
);
|
|
38044
|
+
const nodeAt = React82.useCallback((graphX, graphY) => {
|
|
38045
|
+
return nodesRef.current.find((n) => {
|
|
38046
|
+
const dist = Math.sqrt((n.x - graphX) ** 2 + (n.y - graphY) ** 2);
|
|
38047
|
+
return dist < (n.size || 8) + 4;
|
|
38048
|
+
});
|
|
38049
|
+
}, []);
|
|
38018
38050
|
const handleAction = React82.useCallback(
|
|
38019
38051
|
(action) => {
|
|
38020
38052
|
if (action.event) {
|
|
@@ -38080,7 +38112,7 @@ var init_GraphCanvas = __esm({
|
|
|
38080
38112
|
const dx = nodes[j].x - nodes[i].x;
|
|
38081
38113
|
const dy = nodes[j].y - nodes[i].y;
|
|
38082
38114
|
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
38083
|
-
const force =
|
|
38115
|
+
const force = repulsion / (dist * dist);
|
|
38084
38116
|
const fx = dx / dist * force;
|
|
38085
38117
|
const fy = dy / dist * force;
|
|
38086
38118
|
nodes[i].fx -= fx;
|
|
@@ -38096,7 +38128,7 @@ var init_GraphCanvas = __esm({
|
|
|
38096
38128
|
const dx = target.x - source.x;
|
|
38097
38129
|
const dy = target.y - source.y;
|
|
38098
38130
|
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
38099
|
-
const force = (dist -
|
|
38131
|
+
const force = (dist - linkDistance) * 0.05;
|
|
38100
38132
|
const fx = dx / dist * force;
|
|
38101
38133
|
const fy = dy / dist * force;
|
|
38102
38134
|
source.fx += fx;
|
|
@@ -38130,7 +38162,7 @@ var init_GraphCanvas = __esm({
|
|
|
38130
38162
|
return () => {
|
|
38131
38163
|
cancelAnimationFrame(animRef.current);
|
|
38132
38164
|
};
|
|
38133
|
-
}, [propNodes, propEdges, layout]);
|
|
38165
|
+
}, [propNodes, propEdges, layout, repulsion, linkDistance]);
|
|
38134
38166
|
React82.useEffect(() => {
|
|
38135
38167
|
const canvas = canvasRef.current;
|
|
38136
38168
|
if (!canvas) return;
|
|
@@ -38166,18 +38198,25 @@ var init_GraphCanvas = __esm({
|
|
|
38166
38198
|
const size = node.size || 8;
|
|
38167
38199
|
const color = node.color || getGroupColor(node.group, groups);
|
|
38168
38200
|
const isHovered = hoveredNode === node.id;
|
|
38201
|
+
const isSelected = selectedNodeId !== void 0 && node.id === selectedNodeId;
|
|
38202
|
+
const radius = isSelected ? size + 4 : isHovered ? size + 2 : size;
|
|
38169
38203
|
ctx.beginPath();
|
|
38170
|
-
ctx.arc(node.x, node.y,
|
|
38204
|
+
ctx.arc(node.x, node.y, radius, 0, Math.PI * 2);
|
|
38171
38205
|
ctx.fillStyle = color;
|
|
38172
38206
|
ctx.fill();
|
|
38173
|
-
|
|
38174
|
-
|
|
38207
|
+
if (isSelected) {
|
|
38208
|
+
ctx.strokeStyle = "var(--color-accent)";
|
|
38209
|
+
ctx.lineWidth = 3;
|
|
38210
|
+
} else {
|
|
38211
|
+
ctx.strokeStyle = isHovered ? "#ffffff" : "#00000020";
|
|
38212
|
+
ctx.lineWidth = isHovered ? 2 : 1;
|
|
38213
|
+
}
|
|
38175
38214
|
ctx.stroke();
|
|
38176
38215
|
if (showLabels && node.label) {
|
|
38177
38216
|
ctx.fillStyle = "#666666";
|
|
38178
|
-
ctx.font = `${isHovered ? "bold " : ""}10px system-ui`;
|
|
38217
|
+
ctx.font = `${isSelected || isHovered ? "bold " : ""}10px system-ui`;
|
|
38179
38218
|
ctx.textAlign = "center";
|
|
38180
|
-
ctx.fillText(node.label, node.x, node.y +
|
|
38219
|
+
ctx.fillText(node.label, node.x, node.y + radius + 12);
|
|
38181
38220
|
}
|
|
38182
38221
|
}
|
|
38183
38222
|
ctx.restore();
|
|
@@ -38188,6 +38227,97 @@ var init_GraphCanvas = __esm({
|
|
|
38188
38227
|
setZoom(1);
|
|
38189
38228
|
setOffset({ x: 0, y: 0 });
|
|
38190
38229
|
}, []);
|
|
38230
|
+
const handleWheel = React82.useCallback(
|
|
38231
|
+
(e) => {
|
|
38232
|
+
if (!interactive) return;
|
|
38233
|
+
e.preventDefault();
|
|
38234
|
+
const coords = toCoords(e);
|
|
38235
|
+
if (!coords) return;
|
|
38236
|
+
const oldZoom = zoom;
|
|
38237
|
+
const factor = e.deltaY < 0 ? 1.1 : 1 / 1.1;
|
|
38238
|
+
const newZoom = Math.max(0.3, Math.min(3, oldZoom * factor));
|
|
38239
|
+
if (newZoom === oldZoom) return;
|
|
38240
|
+
setOffset((o) => ({
|
|
38241
|
+
x: coords.screenX - (coords.screenX - o.x) * (newZoom / oldZoom),
|
|
38242
|
+
y: coords.screenY - (coords.screenY - o.y) * (newZoom / oldZoom)
|
|
38243
|
+
}));
|
|
38244
|
+
setZoom(newZoom);
|
|
38245
|
+
},
|
|
38246
|
+
[interactive, toCoords, zoom]
|
|
38247
|
+
);
|
|
38248
|
+
const handleMouseDown = React82.useCallback(
|
|
38249
|
+
(e) => {
|
|
38250
|
+
const coords = toCoords(e);
|
|
38251
|
+
if (!coords) return;
|
|
38252
|
+
const node = nodeAt(coords.graphX, coords.graphY);
|
|
38253
|
+
const state = interactionRef.current;
|
|
38254
|
+
state.downPos = { x: e.clientX, y: e.clientY };
|
|
38255
|
+
state.startMouse = { x: e.clientX, y: e.clientY };
|
|
38256
|
+
state.startOffset = { ...offset };
|
|
38257
|
+
if (draggable && node) {
|
|
38258
|
+
state.mode = "dragging";
|
|
38259
|
+
state.dragNodeId = node.id;
|
|
38260
|
+
} else if (interactive) {
|
|
38261
|
+
state.mode = "panning";
|
|
38262
|
+
state.dragNodeId = null;
|
|
38263
|
+
} else {
|
|
38264
|
+
state.mode = "none";
|
|
38265
|
+
state.dragNodeId = null;
|
|
38266
|
+
}
|
|
38267
|
+
},
|
|
38268
|
+
[toCoords, nodeAt, draggable, interactive, offset]
|
|
38269
|
+
);
|
|
38270
|
+
const handleMouseMove = React82.useCallback(
|
|
38271
|
+
(e) => {
|
|
38272
|
+
const state = interactionRef.current;
|
|
38273
|
+
if (state.mode === "panning") {
|
|
38274
|
+
const dx = e.clientX - state.startMouse.x;
|
|
38275
|
+
const dy = e.clientY - state.startMouse.y;
|
|
38276
|
+
setOffset({ x: state.startOffset.x + dx, y: state.startOffset.y + dy });
|
|
38277
|
+
return;
|
|
38278
|
+
}
|
|
38279
|
+
if (state.mode === "dragging" && state.dragNodeId) {
|
|
38280
|
+
const coords2 = toCoords(e);
|
|
38281
|
+
if (!coords2) return;
|
|
38282
|
+
const node2 = nodesRef.current.find((n) => n.id === state.dragNodeId);
|
|
38283
|
+
if (node2) {
|
|
38284
|
+
node2.x = coords2.graphX;
|
|
38285
|
+
node2.y = coords2.graphY;
|
|
38286
|
+
node2.vx = 0;
|
|
38287
|
+
node2.vy = 0;
|
|
38288
|
+
forceUpdate((n) => n + 1);
|
|
38289
|
+
}
|
|
38290
|
+
return;
|
|
38291
|
+
}
|
|
38292
|
+
const coords = toCoords(e);
|
|
38293
|
+
if (!coords) return;
|
|
38294
|
+
const node = nodeAt(coords.graphX, coords.graphY);
|
|
38295
|
+
setHoveredNode(node?.id ?? null);
|
|
38296
|
+
},
|
|
38297
|
+
[toCoords, nodeAt]
|
|
38298
|
+
);
|
|
38299
|
+
const handleMouseUp = React82.useCallback(
|
|
38300
|
+
(e) => {
|
|
38301
|
+
const state = interactionRef.current;
|
|
38302
|
+
const moved = Math.abs(e.clientX - state.downPos.x) + Math.abs(e.clientY - state.downPos.y);
|
|
38303
|
+
state.mode = "none";
|
|
38304
|
+
state.dragNodeId = null;
|
|
38305
|
+
if (moved < 4) {
|
|
38306
|
+
const coords = toCoords(e);
|
|
38307
|
+
if (!coords) return;
|
|
38308
|
+
const node = nodeAt(coords.graphX, coords.graphY);
|
|
38309
|
+
if (node) {
|
|
38310
|
+
handleNodeClick(node);
|
|
38311
|
+
}
|
|
38312
|
+
}
|
|
38313
|
+
},
|
|
38314
|
+
[toCoords, nodeAt, handleNodeClick]
|
|
38315
|
+
);
|
|
38316
|
+
const handleMouseLeave = React82.useCallback(() => {
|
|
38317
|
+
interactionRef.current.mode = "none";
|
|
38318
|
+
interactionRef.current.dragNodeId = null;
|
|
38319
|
+
setHoveredNode(null);
|
|
38320
|
+
}, []);
|
|
38191
38321
|
if (isLoading) {
|
|
38192
38322
|
return /* @__PURE__ */ jsxRuntime.jsx(LoadingState, { message: t("common.loading"), className });
|
|
38193
38323
|
}
|
|
@@ -38249,20 +38379,11 @@ var init_GraphCanvas = __esm({
|
|
|
38249
38379
|
height,
|
|
38250
38380
|
className: "w-full cursor-grab active:cursor-grabbing",
|
|
38251
38381
|
style: { height },
|
|
38252
|
-
|
|
38253
|
-
|
|
38254
|
-
|
|
38255
|
-
|
|
38256
|
-
|
|
38257
|
-
const y = (e.clientY - rect.top - offset.y) / zoom;
|
|
38258
|
-
const clickedNode = nodesRef.current.find((n) => {
|
|
38259
|
-
const dist = Math.sqrt((n.x - x) ** 2 + (n.y - y) ** 2);
|
|
38260
|
-
return dist < (n.size || 8) + 4;
|
|
38261
|
-
});
|
|
38262
|
-
if (clickedNode) {
|
|
38263
|
-
handleNodeClick(clickedNode);
|
|
38264
|
-
}
|
|
38265
|
-
}
|
|
38382
|
+
onWheel: handleWheel,
|
|
38383
|
+
onMouseDown: handleMouseDown,
|
|
38384
|
+
onMouseMove: handleMouseMove,
|
|
38385
|
+
onMouseUp: handleMouseUp,
|
|
38386
|
+
onMouseLeave: handleMouseLeave
|
|
38266
38387
|
}
|
|
38267
38388
|
) }),
|
|
38268
38389
|
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: [
|
|
@@ -49339,12 +49460,25 @@ function pathToFeatures(path) {
|
|
|
49339
49460
|
sprite: `${CDN6}world-map/road_straight.png`
|
|
49340
49461
|
}));
|
|
49341
49462
|
}
|
|
49463
|
+
function heroToUnit(hero) {
|
|
49464
|
+
return {
|
|
49465
|
+
id: hero.id,
|
|
49466
|
+
position: { x: hero.x, y: hero.y },
|
|
49467
|
+
name: "Hero",
|
|
49468
|
+
team: "player",
|
|
49469
|
+
sprite: HERO_SPRITE,
|
|
49470
|
+
unitType: "amir",
|
|
49471
|
+
health: 1,
|
|
49472
|
+
maxHealth: 1
|
|
49473
|
+
};
|
|
49474
|
+
}
|
|
49342
49475
|
function TowerDefenseBoard({
|
|
49343
49476
|
entity,
|
|
49344
49477
|
tiles: propTiles,
|
|
49345
49478
|
path: propPath,
|
|
49346
49479
|
towers: propTowers,
|
|
49347
49480
|
creeps: propCreeps,
|
|
49481
|
+
hero: propHero,
|
|
49348
49482
|
gold: propGold,
|
|
49349
49483
|
lives: propLives,
|
|
49350
49484
|
wave: propWave,
|
|
@@ -49360,6 +49494,7 @@ function TowerDefenseBoard({
|
|
|
49360
49494
|
startWaveEvent,
|
|
49361
49495
|
playAgainEvent,
|
|
49362
49496
|
gameEndEvent,
|
|
49497
|
+
moveHeroEvent,
|
|
49363
49498
|
className
|
|
49364
49499
|
}) {
|
|
49365
49500
|
const board = boardEntity(entity) ?? {};
|
|
@@ -49371,6 +49506,7 @@ function TowerDefenseBoard({
|
|
|
49371
49506
|
const path = rawPath.length > 0 ? rawPath : DEFAULT_TD_PATH;
|
|
49372
49507
|
const towers = propTowers ?? rows(board.towers);
|
|
49373
49508
|
const creeps = propCreeps ?? rows(board.creeps);
|
|
49509
|
+
const hero = propHero ?? { id: "hero", x: 8, y: 8 };
|
|
49374
49510
|
const gold = propGold ?? num(board.gold, 100);
|
|
49375
49511
|
const lives = propLives ?? num(board.lives, 20);
|
|
49376
49512
|
const wave = propWave ?? num(board.wave, 1);
|
|
@@ -49388,6 +49524,31 @@ function TowerDefenseBoard({
|
|
|
49388
49524
|
if (result === "none") {
|
|
49389
49525
|
emittedGameEnd.current = false;
|
|
49390
49526
|
}
|
|
49527
|
+
const moveHeroEventRef = React82.useRef(moveHeroEvent);
|
|
49528
|
+
moveHeroEventRef.current = moveHeroEvent;
|
|
49529
|
+
const resultRef = React82.useRef(result);
|
|
49530
|
+
resultRef.current = result;
|
|
49531
|
+
React82.useEffect(() => {
|
|
49532
|
+
function onKeyDown(e) {
|
|
49533
|
+
const evt = moveHeroEventRef.current;
|
|
49534
|
+
if (!evt || resultRef.current !== "none") return;
|
|
49535
|
+
let dx = 0;
|
|
49536
|
+
let dy = 0;
|
|
49537
|
+
if (e.key === "ArrowUp") {
|
|
49538
|
+
dy = -1;
|
|
49539
|
+
} else if (e.key === "ArrowDown") {
|
|
49540
|
+
dy = 1;
|
|
49541
|
+
} else if (e.key === "ArrowLeft") {
|
|
49542
|
+
dx = -1;
|
|
49543
|
+
} else if (e.key === "ArrowRight") {
|
|
49544
|
+
dx = 1;
|
|
49545
|
+
} else return;
|
|
49546
|
+
e.preventDefault();
|
|
49547
|
+
eventBus.emit(`UI:${evt}`, { dx, dy });
|
|
49548
|
+
}
|
|
49549
|
+
window.addEventListener("keydown", onKeyDown);
|
|
49550
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
49551
|
+
}, [eventBus]);
|
|
49391
49552
|
const towerPositions = React82.useMemo(() => new Set(towers.map((t2) => `${t2.x},${t2.y}`)), [towers]);
|
|
49392
49553
|
const pathPositions = React82.useMemo(() => new Set(path.map((p2) => `${p2.x},${p2.y}`)), [path]);
|
|
49393
49554
|
const validMoves = React82.useMemo(() => {
|
|
@@ -49399,7 +49560,8 @@ function TowerDefenseBoard({
|
|
|
49399
49560
|
const isoTiles = React82.useMemo(() => tilesToIso(tiles), [tiles]);
|
|
49400
49561
|
const towerUnits = React82.useMemo(() => towersToUnits(towers), [towers]);
|
|
49401
49562
|
const creepUnits = React82.useMemo(() => creepsToUnits(creeps), [creeps]);
|
|
49402
|
-
const
|
|
49563
|
+
const heroUnit = React82.useMemo(() => heroToUnit(hero), [hero]);
|
|
49564
|
+
const isoUnits = React82.useMemo(() => [...towerUnits, ...creepUnits, heroUnit], [towerUnits, creepUnits, heroUnit]);
|
|
49403
49565
|
const pathFeatures = React82.useMemo(() => pathToFeatures(path), [path]);
|
|
49404
49566
|
const handleTileClick = React82.useCallback((x, y) => {
|
|
49405
49567
|
if (result !== "none") return;
|
|
@@ -49498,7 +49660,7 @@ function TowerDefenseBoard({
|
|
|
49498
49660
|
] }) })
|
|
49499
49661
|
] });
|
|
49500
49662
|
}
|
|
49501
|
-
var CDN6, TD_GRID_W, TD_GRID_H, TERRAIN_SPRITES, DEFAULT_TD_PATH, DEFAULT_TD_TILES, TOWER_SPRITE, CREEP_SPRITE;
|
|
49663
|
+
var CDN6, TD_GRID_W, TD_GRID_H, TERRAIN_SPRITES, DEFAULT_TD_PATH, DEFAULT_TD_TILES, TOWER_SPRITE, CREEP_SPRITE, HERO_SPRITE;
|
|
49502
49664
|
var init_TowerDefenseBoard = __esm({
|
|
49503
49665
|
"components/game/organisms/TowerDefenseBoard.tsx"() {
|
|
49504
49666
|
"use client";
|
|
@@ -49572,8 +49734,9 @@ var init_TowerDefenseBoard = __esm({
|
|
|
49572
49734
|
{ x: 13, y: 15 }
|
|
49573
49735
|
];
|
|
49574
49736
|
DEFAULT_TD_TILES = buildDefaultTDTiles();
|
|
49575
|
-
TOWER_SPRITE = `${CDN6}
|
|
49576
|
-
CREEP_SPRITE = `${CDN6}
|
|
49737
|
+
TOWER_SPRITE = `${CDN6}sprite-sheets/guardian-sprite-sheet-se.png`;
|
|
49738
|
+
CREEP_SPRITE = `${CDN6}sprite-sheets/scrapper-sprite-sheet-se.png`;
|
|
49739
|
+
HERO_SPRITE = `${CDN6}sprite-sheets/amir-sprite-sheet-se.png`;
|
|
49577
49740
|
TowerDefenseBoard.displayName = "TowerDefenseBoard";
|
|
49578
49741
|
}
|
|
49579
49742
|
});
|