@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/runtime/index.cjs
CHANGED
|
@@ -29220,13 +29220,13 @@ var init_MapView = __esm({
|
|
|
29220
29220
|
shadowSize: [41, 41]
|
|
29221
29221
|
});
|
|
29222
29222
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
29223
|
-
const { useEffect:
|
|
29223
|
+
const { useEffect: useEffect82, useRef: useRef75, useCallback: useCallback119, useState: useState113 } = React81__namespace.default;
|
|
29224
29224
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
29225
29225
|
const { useEventBus: useEventBus4 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
29226
29226
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
29227
29227
|
const map = useMap();
|
|
29228
29228
|
const prevRef = useRef75({ centerLat, centerLng, zoom });
|
|
29229
|
-
|
|
29229
|
+
useEffect82(() => {
|
|
29230
29230
|
const prev = prevRef.current;
|
|
29231
29231
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
29232
29232
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -29237,7 +29237,7 @@ var init_MapView = __esm({
|
|
|
29237
29237
|
}
|
|
29238
29238
|
function MapClickHandler({ onMapClick }) {
|
|
29239
29239
|
const map = useMap();
|
|
29240
|
-
|
|
29240
|
+
useEffect82(() => {
|
|
29241
29241
|
if (!onMapClick) return;
|
|
29242
29242
|
const handler = (e) => {
|
|
29243
29243
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -37698,6 +37698,9 @@ var init_GraphCanvas = __esm({
|
|
|
37698
37698
|
actions,
|
|
37699
37699
|
onNodeClick,
|
|
37700
37700
|
nodeClickEvent,
|
|
37701
|
+
selectedNodeId,
|
|
37702
|
+
repulsion = 800,
|
|
37703
|
+
linkDistance = 100,
|
|
37701
37704
|
layout = "force",
|
|
37702
37705
|
entity,
|
|
37703
37706
|
isLoading = false,
|
|
@@ -37713,6 +37716,35 @@ var init_GraphCanvas = __esm({
|
|
|
37713
37716
|
const [hoveredNode, setHoveredNode] = React81.useState(null);
|
|
37714
37717
|
const nodesRef = React81.useRef([]);
|
|
37715
37718
|
const [, forceUpdate] = React81.useState(0);
|
|
37719
|
+
const interactionRef = React81.useRef({
|
|
37720
|
+
mode: "none",
|
|
37721
|
+
dragNodeId: null,
|
|
37722
|
+
startMouse: { x: 0, y: 0 },
|
|
37723
|
+
startOffset: { x: 0, y: 0 },
|
|
37724
|
+
downPos: { x: 0, y: 0 }
|
|
37725
|
+
});
|
|
37726
|
+
const toCoords = React81.useCallback(
|
|
37727
|
+
(e) => {
|
|
37728
|
+
const canvas = canvasRef.current;
|
|
37729
|
+
if (!canvas) return null;
|
|
37730
|
+
const rect = canvas.getBoundingClientRect();
|
|
37731
|
+
const screenX = e.clientX - rect.left;
|
|
37732
|
+
const screenY = e.clientY - rect.top;
|
|
37733
|
+
return {
|
|
37734
|
+
screenX,
|
|
37735
|
+
screenY,
|
|
37736
|
+
graphX: (screenX - offset.x) / zoom,
|
|
37737
|
+
graphY: (screenY - offset.y) / zoom
|
|
37738
|
+
};
|
|
37739
|
+
},
|
|
37740
|
+
[offset, zoom]
|
|
37741
|
+
);
|
|
37742
|
+
const nodeAt = React81.useCallback((graphX, graphY) => {
|
|
37743
|
+
return nodesRef.current.find((n) => {
|
|
37744
|
+
const dist = Math.sqrt((n.x - graphX) ** 2 + (n.y - graphY) ** 2);
|
|
37745
|
+
return dist < (n.size || 8) + 4;
|
|
37746
|
+
});
|
|
37747
|
+
}, []);
|
|
37716
37748
|
const handleAction = React81.useCallback(
|
|
37717
37749
|
(action) => {
|
|
37718
37750
|
if (action.event) {
|
|
@@ -37778,7 +37810,7 @@ var init_GraphCanvas = __esm({
|
|
|
37778
37810
|
const dx = nodes[j].x - nodes[i].x;
|
|
37779
37811
|
const dy = nodes[j].y - nodes[i].y;
|
|
37780
37812
|
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
37781
|
-
const force =
|
|
37813
|
+
const force = repulsion / (dist * dist);
|
|
37782
37814
|
const fx = dx / dist * force;
|
|
37783
37815
|
const fy = dy / dist * force;
|
|
37784
37816
|
nodes[i].fx -= fx;
|
|
@@ -37794,7 +37826,7 @@ var init_GraphCanvas = __esm({
|
|
|
37794
37826
|
const dx = target.x - source.x;
|
|
37795
37827
|
const dy = target.y - source.y;
|
|
37796
37828
|
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
37797
|
-
const force = (dist -
|
|
37829
|
+
const force = (dist - linkDistance) * 0.05;
|
|
37798
37830
|
const fx = dx / dist * force;
|
|
37799
37831
|
const fy = dy / dist * force;
|
|
37800
37832
|
source.fx += fx;
|
|
@@ -37828,7 +37860,7 @@ var init_GraphCanvas = __esm({
|
|
|
37828
37860
|
return () => {
|
|
37829
37861
|
cancelAnimationFrame(animRef.current);
|
|
37830
37862
|
};
|
|
37831
|
-
}, [propNodes, propEdges, layout]);
|
|
37863
|
+
}, [propNodes, propEdges, layout, repulsion, linkDistance]);
|
|
37832
37864
|
React81.useEffect(() => {
|
|
37833
37865
|
const canvas = canvasRef.current;
|
|
37834
37866
|
if (!canvas) return;
|
|
@@ -37864,18 +37896,25 @@ var init_GraphCanvas = __esm({
|
|
|
37864
37896
|
const size = node.size || 8;
|
|
37865
37897
|
const color = node.color || getGroupColor(node.group, groups);
|
|
37866
37898
|
const isHovered = hoveredNode === node.id;
|
|
37899
|
+
const isSelected = selectedNodeId !== void 0 && node.id === selectedNodeId;
|
|
37900
|
+
const radius = isSelected ? size + 4 : isHovered ? size + 2 : size;
|
|
37867
37901
|
ctx.beginPath();
|
|
37868
|
-
ctx.arc(node.x, node.y,
|
|
37902
|
+
ctx.arc(node.x, node.y, radius, 0, Math.PI * 2);
|
|
37869
37903
|
ctx.fillStyle = color;
|
|
37870
37904
|
ctx.fill();
|
|
37871
|
-
|
|
37872
|
-
|
|
37905
|
+
if (isSelected) {
|
|
37906
|
+
ctx.strokeStyle = "var(--color-accent)";
|
|
37907
|
+
ctx.lineWidth = 3;
|
|
37908
|
+
} else {
|
|
37909
|
+
ctx.strokeStyle = isHovered ? "#ffffff" : "#00000020";
|
|
37910
|
+
ctx.lineWidth = isHovered ? 2 : 1;
|
|
37911
|
+
}
|
|
37873
37912
|
ctx.stroke();
|
|
37874
37913
|
if (showLabels && node.label) {
|
|
37875
37914
|
ctx.fillStyle = "#666666";
|
|
37876
|
-
ctx.font = `${isHovered ? "bold " : ""}10px system-ui`;
|
|
37915
|
+
ctx.font = `${isSelected || isHovered ? "bold " : ""}10px system-ui`;
|
|
37877
37916
|
ctx.textAlign = "center";
|
|
37878
|
-
ctx.fillText(node.label, node.x, node.y +
|
|
37917
|
+
ctx.fillText(node.label, node.x, node.y + radius + 12);
|
|
37879
37918
|
}
|
|
37880
37919
|
}
|
|
37881
37920
|
ctx.restore();
|
|
@@ -37886,6 +37925,97 @@ var init_GraphCanvas = __esm({
|
|
|
37886
37925
|
setZoom(1);
|
|
37887
37926
|
setOffset({ x: 0, y: 0 });
|
|
37888
37927
|
}, []);
|
|
37928
|
+
const handleWheel = React81.useCallback(
|
|
37929
|
+
(e) => {
|
|
37930
|
+
if (!interactive) return;
|
|
37931
|
+
e.preventDefault();
|
|
37932
|
+
const coords = toCoords(e);
|
|
37933
|
+
if (!coords) return;
|
|
37934
|
+
const oldZoom = zoom;
|
|
37935
|
+
const factor = e.deltaY < 0 ? 1.1 : 1 / 1.1;
|
|
37936
|
+
const newZoom = Math.max(0.3, Math.min(3, oldZoom * factor));
|
|
37937
|
+
if (newZoom === oldZoom) return;
|
|
37938
|
+
setOffset((o) => ({
|
|
37939
|
+
x: coords.screenX - (coords.screenX - o.x) * (newZoom / oldZoom),
|
|
37940
|
+
y: coords.screenY - (coords.screenY - o.y) * (newZoom / oldZoom)
|
|
37941
|
+
}));
|
|
37942
|
+
setZoom(newZoom);
|
|
37943
|
+
},
|
|
37944
|
+
[interactive, toCoords, zoom]
|
|
37945
|
+
);
|
|
37946
|
+
const handleMouseDown = React81.useCallback(
|
|
37947
|
+
(e) => {
|
|
37948
|
+
const coords = toCoords(e);
|
|
37949
|
+
if (!coords) return;
|
|
37950
|
+
const node = nodeAt(coords.graphX, coords.graphY);
|
|
37951
|
+
const state = interactionRef.current;
|
|
37952
|
+
state.downPos = { x: e.clientX, y: e.clientY };
|
|
37953
|
+
state.startMouse = { x: e.clientX, y: e.clientY };
|
|
37954
|
+
state.startOffset = { ...offset };
|
|
37955
|
+
if (draggable && node) {
|
|
37956
|
+
state.mode = "dragging";
|
|
37957
|
+
state.dragNodeId = node.id;
|
|
37958
|
+
} else if (interactive) {
|
|
37959
|
+
state.mode = "panning";
|
|
37960
|
+
state.dragNodeId = null;
|
|
37961
|
+
} else {
|
|
37962
|
+
state.mode = "none";
|
|
37963
|
+
state.dragNodeId = null;
|
|
37964
|
+
}
|
|
37965
|
+
},
|
|
37966
|
+
[toCoords, nodeAt, draggable, interactive, offset]
|
|
37967
|
+
);
|
|
37968
|
+
const handleMouseMove = React81.useCallback(
|
|
37969
|
+
(e) => {
|
|
37970
|
+
const state = interactionRef.current;
|
|
37971
|
+
if (state.mode === "panning") {
|
|
37972
|
+
const dx = e.clientX - state.startMouse.x;
|
|
37973
|
+
const dy = e.clientY - state.startMouse.y;
|
|
37974
|
+
setOffset({ x: state.startOffset.x + dx, y: state.startOffset.y + dy });
|
|
37975
|
+
return;
|
|
37976
|
+
}
|
|
37977
|
+
if (state.mode === "dragging" && state.dragNodeId) {
|
|
37978
|
+
const coords2 = toCoords(e);
|
|
37979
|
+
if (!coords2) return;
|
|
37980
|
+
const node2 = nodesRef.current.find((n) => n.id === state.dragNodeId);
|
|
37981
|
+
if (node2) {
|
|
37982
|
+
node2.x = coords2.graphX;
|
|
37983
|
+
node2.y = coords2.graphY;
|
|
37984
|
+
node2.vx = 0;
|
|
37985
|
+
node2.vy = 0;
|
|
37986
|
+
forceUpdate((n) => n + 1);
|
|
37987
|
+
}
|
|
37988
|
+
return;
|
|
37989
|
+
}
|
|
37990
|
+
const coords = toCoords(e);
|
|
37991
|
+
if (!coords) return;
|
|
37992
|
+
const node = nodeAt(coords.graphX, coords.graphY);
|
|
37993
|
+
setHoveredNode(node?.id ?? null);
|
|
37994
|
+
},
|
|
37995
|
+
[toCoords, nodeAt]
|
|
37996
|
+
);
|
|
37997
|
+
const handleMouseUp = React81.useCallback(
|
|
37998
|
+
(e) => {
|
|
37999
|
+
const state = interactionRef.current;
|
|
38000
|
+
const moved = Math.abs(e.clientX - state.downPos.x) + Math.abs(e.clientY - state.downPos.y);
|
|
38001
|
+
state.mode = "none";
|
|
38002
|
+
state.dragNodeId = null;
|
|
38003
|
+
if (moved < 4) {
|
|
38004
|
+
const coords = toCoords(e);
|
|
38005
|
+
if (!coords) return;
|
|
38006
|
+
const node = nodeAt(coords.graphX, coords.graphY);
|
|
38007
|
+
if (node) {
|
|
38008
|
+
handleNodeClick(node);
|
|
38009
|
+
}
|
|
38010
|
+
}
|
|
38011
|
+
},
|
|
38012
|
+
[toCoords, nodeAt, handleNodeClick]
|
|
38013
|
+
);
|
|
38014
|
+
const handleMouseLeave = React81.useCallback(() => {
|
|
38015
|
+
interactionRef.current.mode = "none";
|
|
38016
|
+
interactionRef.current.dragNodeId = null;
|
|
38017
|
+
setHoveredNode(null);
|
|
38018
|
+
}, []);
|
|
37889
38019
|
if (isLoading) {
|
|
37890
38020
|
return /* @__PURE__ */ jsxRuntime.jsx(LoadingState, { message: t("common.loading"), className });
|
|
37891
38021
|
}
|
|
@@ -37947,20 +38077,11 @@ var init_GraphCanvas = __esm({
|
|
|
37947
38077
|
height,
|
|
37948
38078
|
className: "w-full cursor-grab active:cursor-grabbing",
|
|
37949
38079
|
style: { height },
|
|
37950
|
-
|
|
37951
|
-
|
|
37952
|
-
|
|
37953
|
-
|
|
37954
|
-
|
|
37955
|
-
const y = (e.clientY - rect.top - offset.y) / zoom;
|
|
37956
|
-
const clickedNode = nodesRef.current.find((n) => {
|
|
37957
|
-
const dist = Math.sqrt((n.x - x) ** 2 + (n.y - y) ** 2);
|
|
37958
|
-
return dist < (n.size || 8) + 4;
|
|
37959
|
-
});
|
|
37960
|
-
if (clickedNode) {
|
|
37961
|
-
handleNodeClick(clickedNode);
|
|
37962
|
-
}
|
|
37963
|
-
}
|
|
38080
|
+
onWheel: handleWheel,
|
|
38081
|
+
onMouseDown: handleMouseDown,
|
|
38082
|
+
onMouseMove: handleMouseMove,
|
|
38083
|
+
onMouseUp: handleMouseUp,
|
|
38084
|
+
onMouseLeave: handleMouseLeave
|
|
37964
38085
|
}
|
|
37965
38086
|
) }),
|
|
37966
38087
|
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: [
|
|
@@ -49056,12 +49177,25 @@ function pathToFeatures(path) {
|
|
|
49056
49177
|
sprite: `${CDN6}world-map/road_straight.png`
|
|
49057
49178
|
}));
|
|
49058
49179
|
}
|
|
49180
|
+
function heroToUnit(hero) {
|
|
49181
|
+
return {
|
|
49182
|
+
id: hero.id,
|
|
49183
|
+
position: { x: hero.x, y: hero.y },
|
|
49184
|
+
name: "Hero",
|
|
49185
|
+
team: "player",
|
|
49186
|
+
sprite: HERO_SPRITE,
|
|
49187
|
+
unitType: "amir",
|
|
49188
|
+
health: 1,
|
|
49189
|
+
maxHealth: 1
|
|
49190
|
+
};
|
|
49191
|
+
}
|
|
49059
49192
|
function TowerDefenseBoard({
|
|
49060
49193
|
entity,
|
|
49061
49194
|
tiles: propTiles,
|
|
49062
49195
|
path: propPath,
|
|
49063
49196
|
towers: propTowers,
|
|
49064
49197
|
creeps: propCreeps,
|
|
49198
|
+
hero: propHero,
|
|
49065
49199
|
gold: propGold,
|
|
49066
49200
|
lives: propLives,
|
|
49067
49201
|
wave: propWave,
|
|
@@ -49077,6 +49211,7 @@ function TowerDefenseBoard({
|
|
|
49077
49211
|
startWaveEvent,
|
|
49078
49212
|
playAgainEvent,
|
|
49079
49213
|
gameEndEvent,
|
|
49214
|
+
moveHeroEvent,
|
|
49080
49215
|
className
|
|
49081
49216
|
}) {
|
|
49082
49217
|
const board = boardEntity(entity) ?? {};
|
|
@@ -49088,6 +49223,7 @@ function TowerDefenseBoard({
|
|
|
49088
49223
|
const path = rawPath.length > 0 ? rawPath : DEFAULT_TD_PATH;
|
|
49089
49224
|
const towers = propTowers ?? rows(board.towers);
|
|
49090
49225
|
const creeps = propCreeps ?? rows(board.creeps);
|
|
49226
|
+
const hero = propHero ?? { id: "hero", x: 8, y: 8 };
|
|
49091
49227
|
const gold = propGold ?? num(board.gold, 100);
|
|
49092
49228
|
const lives = propLives ?? num(board.lives, 20);
|
|
49093
49229
|
const wave = propWave ?? num(board.wave, 1);
|
|
@@ -49105,6 +49241,31 @@ function TowerDefenseBoard({
|
|
|
49105
49241
|
if (result === "none") {
|
|
49106
49242
|
emittedGameEnd.current = false;
|
|
49107
49243
|
}
|
|
49244
|
+
const moveHeroEventRef = React81.useRef(moveHeroEvent);
|
|
49245
|
+
moveHeroEventRef.current = moveHeroEvent;
|
|
49246
|
+
const resultRef = React81.useRef(result);
|
|
49247
|
+
resultRef.current = result;
|
|
49248
|
+
React81.useEffect(() => {
|
|
49249
|
+
function onKeyDown(e) {
|
|
49250
|
+
const evt = moveHeroEventRef.current;
|
|
49251
|
+
if (!evt || resultRef.current !== "none") return;
|
|
49252
|
+
let dx = 0;
|
|
49253
|
+
let dy = 0;
|
|
49254
|
+
if (e.key === "ArrowUp") {
|
|
49255
|
+
dy = -1;
|
|
49256
|
+
} else if (e.key === "ArrowDown") {
|
|
49257
|
+
dy = 1;
|
|
49258
|
+
} else if (e.key === "ArrowLeft") {
|
|
49259
|
+
dx = -1;
|
|
49260
|
+
} else if (e.key === "ArrowRight") {
|
|
49261
|
+
dx = 1;
|
|
49262
|
+
} else return;
|
|
49263
|
+
e.preventDefault();
|
|
49264
|
+
eventBus.emit(`UI:${evt}`, { dx, dy });
|
|
49265
|
+
}
|
|
49266
|
+
window.addEventListener("keydown", onKeyDown);
|
|
49267
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
49268
|
+
}, [eventBus]);
|
|
49108
49269
|
const towerPositions = React81.useMemo(() => new Set(towers.map((t2) => `${t2.x},${t2.y}`)), [towers]);
|
|
49109
49270
|
const pathPositions = React81.useMemo(() => new Set(path.map((p2) => `${p2.x},${p2.y}`)), [path]);
|
|
49110
49271
|
const validMoves = React81.useMemo(() => {
|
|
@@ -49116,7 +49277,8 @@ function TowerDefenseBoard({
|
|
|
49116
49277
|
const isoTiles = React81.useMemo(() => tilesToIso(tiles), [tiles]);
|
|
49117
49278
|
const towerUnits = React81.useMemo(() => towersToUnits(towers), [towers]);
|
|
49118
49279
|
const creepUnits = React81.useMemo(() => creepsToUnits(creeps), [creeps]);
|
|
49119
|
-
const
|
|
49280
|
+
const heroUnit = React81.useMemo(() => heroToUnit(hero), [hero]);
|
|
49281
|
+
const isoUnits = React81.useMemo(() => [...towerUnits, ...creepUnits, heroUnit], [towerUnits, creepUnits, heroUnit]);
|
|
49120
49282
|
const pathFeatures = React81.useMemo(() => pathToFeatures(path), [path]);
|
|
49121
49283
|
const handleTileClick = React81.useCallback((x, y) => {
|
|
49122
49284
|
if (result !== "none") return;
|
|
@@ -49215,7 +49377,7 @@ function TowerDefenseBoard({
|
|
|
49215
49377
|
] }) })
|
|
49216
49378
|
] });
|
|
49217
49379
|
}
|
|
49218
|
-
var CDN6, TD_GRID_W, TD_GRID_H, TERRAIN_SPRITES, DEFAULT_TD_PATH, DEFAULT_TD_TILES, TOWER_SPRITE, CREEP_SPRITE;
|
|
49380
|
+
var CDN6, TD_GRID_W, TD_GRID_H, TERRAIN_SPRITES, DEFAULT_TD_PATH, DEFAULT_TD_TILES, TOWER_SPRITE, CREEP_SPRITE, HERO_SPRITE;
|
|
49219
49381
|
var init_TowerDefenseBoard = __esm({
|
|
49220
49382
|
"components/game/organisms/TowerDefenseBoard.tsx"() {
|
|
49221
49383
|
"use client";
|
|
@@ -49289,8 +49451,9 @@ var init_TowerDefenseBoard = __esm({
|
|
|
49289
49451
|
{ x: 13, y: 15 }
|
|
49290
49452
|
];
|
|
49291
49453
|
DEFAULT_TD_TILES = buildDefaultTDTiles();
|
|
49292
|
-
TOWER_SPRITE = `${CDN6}
|
|
49293
|
-
CREEP_SPRITE = `${CDN6}
|
|
49454
|
+
TOWER_SPRITE = `${CDN6}sprite-sheets/guardian-sprite-sheet-se.png`;
|
|
49455
|
+
CREEP_SPRITE = `${CDN6}sprite-sheets/scrapper-sprite-sheet-se.png`;
|
|
49456
|
+
HERO_SPRITE = `${CDN6}sprite-sheets/amir-sprite-sheet-se.png`;
|
|
49294
49457
|
TowerDefenseBoard.displayName = "TowerDefenseBoard";
|
|
49295
49458
|
}
|
|
49296
49459
|
});
|