@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.js
CHANGED
|
@@ -29173,13 +29173,13 @@ var init_MapView = __esm({
|
|
|
29173
29173
|
shadowSize: [41, 41]
|
|
29174
29174
|
});
|
|
29175
29175
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
29176
|
-
const { useEffect:
|
|
29176
|
+
const { useEffect: useEffect82, useRef: useRef75, useCallback: useCallback119, useState: useState113 } = React81__default;
|
|
29177
29177
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
29178
29178
|
const { useEventBus: useEventBus4 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
29179
29179
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
29180
29180
|
const map = useMap();
|
|
29181
29181
|
const prevRef = useRef75({ centerLat, centerLng, zoom });
|
|
29182
|
-
|
|
29182
|
+
useEffect82(() => {
|
|
29183
29183
|
const prev = prevRef.current;
|
|
29184
29184
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
29185
29185
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -29190,7 +29190,7 @@ var init_MapView = __esm({
|
|
|
29190
29190
|
}
|
|
29191
29191
|
function MapClickHandler({ onMapClick }) {
|
|
29192
29192
|
const map = useMap();
|
|
29193
|
-
|
|
29193
|
+
useEffect82(() => {
|
|
29194
29194
|
if (!onMapClick) return;
|
|
29195
29195
|
const handler = (e) => {
|
|
29196
29196
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -37651,6 +37651,9 @@ var init_GraphCanvas = __esm({
|
|
|
37651
37651
|
actions,
|
|
37652
37652
|
onNodeClick,
|
|
37653
37653
|
nodeClickEvent,
|
|
37654
|
+
selectedNodeId,
|
|
37655
|
+
repulsion = 800,
|
|
37656
|
+
linkDistance = 100,
|
|
37654
37657
|
layout = "force",
|
|
37655
37658
|
entity,
|
|
37656
37659
|
isLoading = false,
|
|
@@ -37666,6 +37669,35 @@ var init_GraphCanvas = __esm({
|
|
|
37666
37669
|
const [hoveredNode, setHoveredNode] = useState(null);
|
|
37667
37670
|
const nodesRef = useRef([]);
|
|
37668
37671
|
const [, forceUpdate] = useState(0);
|
|
37672
|
+
const interactionRef = useRef({
|
|
37673
|
+
mode: "none",
|
|
37674
|
+
dragNodeId: null,
|
|
37675
|
+
startMouse: { x: 0, y: 0 },
|
|
37676
|
+
startOffset: { x: 0, y: 0 },
|
|
37677
|
+
downPos: { x: 0, y: 0 }
|
|
37678
|
+
});
|
|
37679
|
+
const toCoords = useCallback(
|
|
37680
|
+
(e) => {
|
|
37681
|
+
const canvas = canvasRef.current;
|
|
37682
|
+
if (!canvas) return null;
|
|
37683
|
+
const rect = canvas.getBoundingClientRect();
|
|
37684
|
+
const screenX = e.clientX - rect.left;
|
|
37685
|
+
const screenY = e.clientY - rect.top;
|
|
37686
|
+
return {
|
|
37687
|
+
screenX,
|
|
37688
|
+
screenY,
|
|
37689
|
+
graphX: (screenX - offset.x) / zoom,
|
|
37690
|
+
graphY: (screenY - offset.y) / zoom
|
|
37691
|
+
};
|
|
37692
|
+
},
|
|
37693
|
+
[offset, zoom]
|
|
37694
|
+
);
|
|
37695
|
+
const nodeAt = useCallback((graphX, graphY) => {
|
|
37696
|
+
return nodesRef.current.find((n) => {
|
|
37697
|
+
const dist = Math.sqrt((n.x - graphX) ** 2 + (n.y - graphY) ** 2);
|
|
37698
|
+
return dist < (n.size || 8) + 4;
|
|
37699
|
+
});
|
|
37700
|
+
}, []);
|
|
37669
37701
|
const handleAction = useCallback(
|
|
37670
37702
|
(action) => {
|
|
37671
37703
|
if (action.event) {
|
|
@@ -37731,7 +37763,7 @@ var init_GraphCanvas = __esm({
|
|
|
37731
37763
|
const dx = nodes[j].x - nodes[i].x;
|
|
37732
37764
|
const dy = nodes[j].y - nodes[i].y;
|
|
37733
37765
|
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
37734
|
-
const force =
|
|
37766
|
+
const force = repulsion / (dist * dist);
|
|
37735
37767
|
const fx = dx / dist * force;
|
|
37736
37768
|
const fy = dy / dist * force;
|
|
37737
37769
|
nodes[i].fx -= fx;
|
|
@@ -37747,7 +37779,7 @@ var init_GraphCanvas = __esm({
|
|
|
37747
37779
|
const dx = target.x - source.x;
|
|
37748
37780
|
const dy = target.y - source.y;
|
|
37749
37781
|
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
37750
|
-
const force = (dist -
|
|
37782
|
+
const force = (dist - linkDistance) * 0.05;
|
|
37751
37783
|
const fx = dx / dist * force;
|
|
37752
37784
|
const fy = dy / dist * force;
|
|
37753
37785
|
source.fx += fx;
|
|
@@ -37781,7 +37813,7 @@ var init_GraphCanvas = __esm({
|
|
|
37781
37813
|
return () => {
|
|
37782
37814
|
cancelAnimationFrame(animRef.current);
|
|
37783
37815
|
};
|
|
37784
|
-
}, [propNodes, propEdges, layout]);
|
|
37816
|
+
}, [propNodes, propEdges, layout, repulsion, linkDistance]);
|
|
37785
37817
|
useEffect(() => {
|
|
37786
37818
|
const canvas = canvasRef.current;
|
|
37787
37819
|
if (!canvas) return;
|
|
@@ -37817,18 +37849,25 @@ var init_GraphCanvas = __esm({
|
|
|
37817
37849
|
const size = node.size || 8;
|
|
37818
37850
|
const color = node.color || getGroupColor(node.group, groups);
|
|
37819
37851
|
const isHovered = hoveredNode === node.id;
|
|
37852
|
+
const isSelected = selectedNodeId !== void 0 && node.id === selectedNodeId;
|
|
37853
|
+
const radius = isSelected ? size + 4 : isHovered ? size + 2 : size;
|
|
37820
37854
|
ctx.beginPath();
|
|
37821
|
-
ctx.arc(node.x, node.y,
|
|
37855
|
+
ctx.arc(node.x, node.y, radius, 0, Math.PI * 2);
|
|
37822
37856
|
ctx.fillStyle = color;
|
|
37823
37857
|
ctx.fill();
|
|
37824
|
-
|
|
37825
|
-
|
|
37858
|
+
if (isSelected) {
|
|
37859
|
+
ctx.strokeStyle = "var(--color-accent)";
|
|
37860
|
+
ctx.lineWidth = 3;
|
|
37861
|
+
} else {
|
|
37862
|
+
ctx.strokeStyle = isHovered ? "#ffffff" : "#00000020";
|
|
37863
|
+
ctx.lineWidth = isHovered ? 2 : 1;
|
|
37864
|
+
}
|
|
37826
37865
|
ctx.stroke();
|
|
37827
37866
|
if (showLabels && node.label) {
|
|
37828
37867
|
ctx.fillStyle = "#666666";
|
|
37829
|
-
ctx.font = `${isHovered ? "bold " : ""}10px system-ui`;
|
|
37868
|
+
ctx.font = `${isSelected || isHovered ? "bold " : ""}10px system-ui`;
|
|
37830
37869
|
ctx.textAlign = "center";
|
|
37831
|
-
ctx.fillText(node.label, node.x, node.y +
|
|
37870
|
+
ctx.fillText(node.label, node.x, node.y + radius + 12);
|
|
37832
37871
|
}
|
|
37833
37872
|
}
|
|
37834
37873
|
ctx.restore();
|
|
@@ -37839,6 +37878,97 @@ var init_GraphCanvas = __esm({
|
|
|
37839
37878
|
setZoom(1);
|
|
37840
37879
|
setOffset({ x: 0, y: 0 });
|
|
37841
37880
|
}, []);
|
|
37881
|
+
const handleWheel = useCallback(
|
|
37882
|
+
(e) => {
|
|
37883
|
+
if (!interactive) return;
|
|
37884
|
+
e.preventDefault();
|
|
37885
|
+
const coords = toCoords(e);
|
|
37886
|
+
if (!coords) return;
|
|
37887
|
+
const oldZoom = zoom;
|
|
37888
|
+
const factor = e.deltaY < 0 ? 1.1 : 1 / 1.1;
|
|
37889
|
+
const newZoom = Math.max(0.3, Math.min(3, oldZoom * factor));
|
|
37890
|
+
if (newZoom === oldZoom) return;
|
|
37891
|
+
setOffset((o) => ({
|
|
37892
|
+
x: coords.screenX - (coords.screenX - o.x) * (newZoom / oldZoom),
|
|
37893
|
+
y: coords.screenY - (coords.screenY - o.y) * (newZoom / oldZoom)
|
|
37894
|
+
}));
|
|
37895
|
+
setZoom(newZoom);
|
|
37896
|
+
},
|
|
37897
|
+
[interactive, toCoords, zoom]
|
|
37898
|
+
);
|
|
37899
|
+
const handleMouseDown = useCallback(
|
|
37900
|
+
(e) => {
|
|
37901
|
+
const coords = toCoords(e);
|
|
37902
|
+
if (!coords) return;
|
|
37903
|
+
const node = nodeAt(coords.graphX, coords.graphY);
|
|
37904
|
+
const state = interactionRef.current;
|
|
37905
|
+
state.downPos = { x: e.clientX, y: e.clientY };
|
|
37906
|
+
state.startMouse = { x: e.clientX, y: e.clientY };
|
|
37907
|
+
state.startOffset = { ...offset };
|
|
37908
|
+
if (draggable && node) {
|
|
37909
|
+
state.mode = "dragging";
|
|
37910
|
+
state.dragNodeId = node.id;
|
|
37911
|
+
} else if (interactive) {
|
|
37912
|
+
state.mode = "panning";
|
|
37913
|
+
state.dragNodeId = null;
|
|
37914
|
+
} else {
|
|
37915
|
+
state.mode = "none";
|
|
37916
|
+
state.dragNodeId = null;
|
|
37917
|
+
}
|
|
37918
|
+
},
|
|
37919
|
+
[toCoords, nodeAt, draggable, interactive, offset]
|
|
37920
|
+
);
|
|
37921
|
+
const handleMouseMove = useCallback(
|
|
37922
|
+
(e) => {
|
|
37923
|
+
const state = interactionRef.current;
|
|
37924
|
+
if (state.mode === "panning") {
|
|
37925
|
+
const dx = e.clientX - state.startMouse.x;
|
|
37926
|
+
const dy = e.clientY - state.startMouse.y;
|
|
37927
|
+
setOffset({ x: state.startOffset.x + dx, y: state.startOffset.y + dy });
|
|
37928
|
+
return;
|
|
37929
|
+
}
|
|
37930
|
+
if (state.mode === "dragging" && state.dragNodeId) {
|
|
37931
|
+
const coords2 = toCoords(e);
|
|
37932
|
+
if (!coords2) return;
|
|
37933
|
+
const node2 = nodesRef.current.find((n) => n.id === state.dragNodeId);
|
|
37934
|
+
if (node2) {
|
|
37935
|
+
node2.x = coords2.graphX;
|
|
37936
|
+
node2.y = coords2.graphY;
|
|
37937
|
+
node2.vx = 0;
|
|
37938
|
+
node2.vy = 0;
|
|
37939
|
+
forceUpdate((n) => n + 1);
|
|
37940
|
+
}
|
|
37941
|
+
return;
|
|
37942
|
+
}
|
|
37943
|
+
const coords = toCoords(e);
|
|
37944
|
+
if (!coords) return;
|
|
37945
|
+
const node = nodeAt(coords.graphX, coords.graphY);
|
|
37946
|
+
setHoveredNode(node?.id ?? null);
|
|
37947
|
+
},
|
|
37948
|
+
[toCoords, nodeAt]
|
|
37949
|
+
);
|
|
37950
|
+
const handleMouseUp = useCallback(
|
|
37951
|
+
(e) => {
|
|
37952
|
+
const state = interactionRef.current;
|
|
37953
|
+
const moved = Math.abs(e.clientX - state.downPos.x) + Math.abs(e.clientY - state.downPos.y);
|
|
37954
|
+
state.mode = "none";
|
|
37955
|
+
state.dragNodeId = null;
|
|
37956
|
+
if (moved < 4) {
|
|
37957
|
+
const coords = toCoords(e);
|
|
37958
|
+
if (!coords) return;
|
|
37959
|
+
const node = nodeAt(coords.graphX, coords.graphY);
|
|
37960
|
+
if (node) {
|
|
37961
|
+
handleNodeClick(node);
|
|
37962
|
+
}
|
|
37963
|
+
}
|
|
37964
|
+
},
|
|
37965
|
+
[toCoords, nodeAt, handleNodeClick]
|
|
37966
|
+
);
|
|
37967
|
+
const handleMouseLeave = useCallback(() => {
|
|
37968
|
+
interactionRef.current.mode = "none";
|
|
37969
|
+
interactionRef.current.dragNodeId = null;
|
|
37970
|
+
setHoveredNode(null);
|
|
37971
|
+
}, []);
|
|
37842
37972
|
if (isLoading) {
|
|
37843
37973
|
return /* @__PURE__ */ jsx(LoadingState, { message: t("common.loading"), className });
|
|
37844
37974
|
}
|
|
@@ -37900,20 +38030,11 @@ var init_GraphCanvas = __esm({
|
|
|
37900
38030
|
height,
|
|
37901
38031
|
className: "w-full cursor-grab active:cursor-grabbing",
|
|
37902
38032
|
style: { height },
|
|
37903
|
-
|
|
37904
|
-
|
|
37905
|
-
|
|
37906
|
-
|
|
37907
|
-
|
|
37908
|
-
const y = (e.clientY - rect.top - offset.y) / zoom;
|
|
37909
|
-
const clickedNode = nodesRef.current.find((n) => {
|
|
37910
|
-
const dist = Math.sqrt((n.x - x) ** 2 + (n.y - y) ** 2);
|
|
37911
|
-
return dist < (n.size || 8) + 4;
|
|
37912
|
-
});
|
|
37913
|
-
if (clickedNode) {
|
|
37914
|
-
handleNodeClick(clickedNode);
|
|
37915
|
-
}
|
|
37916
|
-
}
|
|
38033
|
+
onWheel: handleWheel,
|
|
38034
|
+
onMouseDown: handleMouseDown,
|
|
38035
|
+
onMouseMove: handleMouseMove,
|
|
38036
|
+
onMouseUp: handleMouseUp,
|
|
38037
|
+
onMouseLeave: handleMouseLeave
|
|
37917
38038
|
}
|
|
37918
38039
|
) }),
|
|
37919
38040
|
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: [
|
|
@@ -49009,12 +49130,25 @@ function pathToFeatures(path) {
|
|
|
49009
49130
|
sprite: `${CDN6}world-map/road_straight.png`
|
|
49010
49131
|
}));
|
|
49011
49132
|
}
|
|
49133
|
+
function heroToUnit(hero) {
|
|
49134
|
+
return {
|
|
49135
|
+
id: hero.id,
|
|
49136
|
+
position: { x: hero.x, y: hero.y },
|
|
49137
|
+
name: "Hero",
|
|
49138
|
+
team: "player",
|
|
49139
|
+
sprite: HERO_SPRITE,
|
|
49140
|
+
unitType: "amir",
|
|
49141
|
+
health: 1,
|
|
49142
|
+
maxHealth: 1
|
|
49143
|
+
};
|
|
49144
|
+
}
|
|
49012
49145
|
function TowerDefenseBoard({
|
|
49013
49146
|
entity,
|
|
49014
49147
|
tiles: propTiles,
|
|
49015
49148
|
path: propPath,
|
|
49016
49149
|
towers: propTowers,
|
|
49017
49150
|
creeps: propCreeps,
|
|
49151
|
+
hero: propHero,
|
|
49018
49152
|
gold: propGold,
|
|
49019
49153
|
lives: propLives,
|
|
49020
49154
|
wave: propWave,
|
|
@@ -49030,6 +49164,7 @@ function TowerDefenseBoard({
|
|
|
49030
49164
|
startWaveEvent,
|
|
49031
49165
|
playAgainEvent,
|
|
49032
49166
|
gameEndEvent,
|
|
49167
|
+
moveHeroEvent,
|
|
49033
49168
|
className
|
|
49034
49169
|
}) {
|
|
49035
49170
|
const board = boardEntity(entity) ?? {};
|
|
@@ -49041,6 +49176,7 @@ function TowerDefenseBoard({
|
|
|
49041
49176
|
const path = rawPath.length > 0 ? rawPath : DEFAULT_TD_PATH;
|
|
49042
49177
|
const towers = propTowers ?? rows(board.towers);
|
|
49043
49178
|
const creeps = propCreeps ?? rows(board.creeps);
|
|
49179
|
+
const hero = propHero ?? { id: "hero", x: 8, y: 8 };
|
|
49044
49180
|
const gold = propGold ?? num(board.gold, 100);
|
|
49045
49181
|
const lives = propLives ?? num(board.lives, 20);
|
|
49046
49182
|
const wave = propWave ?? num(board.wave, 1);
|
|
@@ -49058,6 +49194,31 @@ function TowerDefenseBoard({
|
|
|
49058
49194
|
if (result === "none") {
|
|
49059
49195
|
emittedGameEnd.current = false;
|
|
49060
49196
|
}
|
|
49197
|
+
const moveHeroEventRef = useRef(moveHeroEvent);
|
|
49198
|
+
moveHeroEventRef.current = moveHeroEvent;
|
|
49199
|
+
const resultRef = useRef(result);
|
|
49200
|
+
resultRef.current = result;
|
|
49201
|
+
useEffect(() => {
|
|
49202
|
+
function onKeyDown(e) {
|
|
49203
|
+
const evt = moveHeroEventRef.current;
|
|
49204
|
+
if (!evt || resultRef.current !== "none") return;
|
|
49205
|
+
let dx = 0;
|
|
49206
|
+
let dy = 0;
|
|
49207
|
+
if (e.key === "ArrowUp") {
|
|
49208
|
+
dy = -1;
|
|
49209
|
+
} else if (e.key === "ArrowDown") {
|
|
49210
|
+
dy = 1;
|
|
49211
|
+
} else if (e.key === "ArrowLeft") {
|
|
49212
|
+
dx = -1;
|
|
49213
|
+
} else if (e.key === "ArrowRight") {
|
|
49214
|
+
dx = 1;
|
|
49215
|
+
} else return;
|
|
49216
|
+
e.preventDefault();
|
|
49217
|
+
eventBus.emit(`UI:${evt}`, { dx, dy });
|
|
49218
|
+
}
|
|
49219
|
+
window.addEventListener("keydown", onKeyDown);
|
|
49220
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
49221
|
+
}, [eventBus]);
|
|
49061
49222
|
const towerPositions = useMemo(() => new Set(towers.map((t2) => `${t2.x},${t2.y}`)), [towers]);
|
|
49062
49223
|
const pathPositions = useMemo(() => new Set(path.map((p2) => `${p2.x},${p2.y}`)), [path]);
|
|
49063
49224
|
const validMoves = useMemo(() => {
|
|
@@ -49069,7 +49230,8 @@ function TowerDefenseBoard({
|
|
|
49069
49230
|
const isoTiles = useMemo(() => tilesToIso(tiles), [tiles]);
|
|
49070
49231
|
const towerUnits = useMemo(() => towersToUnits(towers), [towers]);
|
|
49071
49232
|
const creepUnits = useMemo(() => creepsToUnits(creeps), [creeps]);
|
|
49072
|
-
const
|
|
49233
|
+
const heroUnit = useMemo(() => heroToUnit(hero), [hero]);
|
|
49234
|
+
const isoUnits = useMemo(() => [...towerUnits, ...creepUnits, heroUnit], [towerUnits, creepUnits, heroUnit]);
|
|
49073
49235
|
const pathFeatures = useMemo(() => pathToFeatures(path), [path]);
|
|
49074
49236
|
const handleTileClick = useCallback((x, y) => {
|
|
49075
49237
|
if (result !== "none") return;
|
|
@@ -49168,7 +49330,7 @@ function TowerDefenseBoard({
|
|
|
49168
49330
|
] }) })
|
|
49169
49331
|
] });
|
|
49170
49332
|
}
|
|
49171
|
-
var CDN6, TD_GRID_W, TD_GRID_H, TERRAIN_SPRITES, DEFAULT_TD_PATH, DEFAULT_TD_TILES, TOWER_SPRITE, CREEP_SPRITE;
|
|
49333
|
+
var CDN6, TD_GRID_W, TD_GRID_H, TERRAIN_SPRITES, DEFAULT_TD_PATH, DEFAULT_TD_TILES, TOWER_SPRITE, CREEP_SPRITE, HERO_SPRITE;
|
|
49172
49334
|
var init_TowerDefenseBoard = __esm({
|
|
49173
49335
|
"components/game/organisms/TowerDefenseBoard.tsx"() {
|
|
49174
49336
|
"use client";
|
|
@@ -49242,8 +49404,9 @@ var init_TowerDefenseBoard = __esm({
|
|
|
49242
49404
|
{ x: 13, y: 15 }
|
|
49243
49405
|
];
|
|
49244
49406
|
DEFAULT_TD_TILES = buildDefaultTDTiles();
|
|
49245
|
-
TOWER_SPRITE = `${CDN6}
|
|
49246
|
-
CREEP_SPRITE = `${CDN6}
|
|
49407
|
+
TOWER_SPRITE = `${CDN6}sprite-sheets/guardian-sprite-sheet-se.png`;
|
|
49408
|
+
CREEP_SPRITE = `${CDN6}sprite-sheets/scrapper-sprite-sheet-se.png`;
|
|
49409
|
+
HERO_SPRITE = `${CDN6}sprite-sheets/amir-sprite-sheet-se.png`;
|
|
49247
49410
|
TowerDefenseBoard.displayName = "TowerDefenseBoard";
|
|
49248
49411
|
}
|
|
49249
49412
|
});
|