mudlet-map-renderer 1.0.0 → 1.1.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/README.md +520 -0
- package/dist/AreaMapRenderer.d.ts +125 -0
- package/dist/CullingManager.d.ts +15 -0
- package/dist/ExitRenderer.d.ts +109 -0
- package/dist/InteractionHandler.d.ts +47 -0
- package/dist/MapGraph.d.ts +28 -0
- package/dist/MapReader-mU_4JWv_.js +224 -0
- package/dist/MapReader-mU_4JWv_.js.map +1 -0
- package/dist/MapState.d.ts +110 -0
- package/dist/PathData.d.ts +18 -0
- package/dist/PathFinder.d.ts +12 -0
- package/dist/ScenePipeline.d.ts +226 -0
- package/dist/SvgTypes.d.ts +21 -0
- package/dist/TypedEventEmitter.d.ts +17 -0
- package/dist/binary/BinaryMapReader.d.ts +36 -0
- package/dist/binary/index.d.ts +2 -0
- package/dist/binary.mjs +34 -0
- package/dist/binary.mjs.map +1 -0
- package/dist/camera/Camera.d.ts +106 -0
- package/dist/coord/CoordFn.d.ts +13 -0
- package/dist/directions.d.ts +25 -0
- package/dist/draw/DrawCommand.d.ts +104 -0
- package/dist/draw/DrawCommandBuilder.d.ts +19 -0
- package/dist/export/CanvasExporter.d.ts +71 -0
- package/dist/export/Exporter.d.ts +58 -0
- package/dist/export/PngExporter.d.ts +23 -0
- package/dist/export/SvgExporter.d.ts +19 -0
- package/dist/export/canvasToBytes.d.ts +19 -0
- package/dist/export/clipSceneToViewport.d.ts +48 -0
- package/dist/export/flushSceneShapes.d.ts +21 -0
- package/dist/export/sceneBounds.d.ts +24 -0
- package/dist/hit/HitTester.d.ts +101 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.mjs +6656 -0
- package/dist/index.mjs.map +1 -0
- package/dist/lens/ExplorationLens.d.ts +29 -0
- package/dist/lens/RoomLens.d.ts +47 -0
- package/dist/lens/composeLenses.d.ts +31 -0
- package/dist/lens/index.d.ts +5 -0
- package/dist/overlay/AmbientLightOverlay.d.ts +32 -0
- package/dist/overlay/LiveEffect.d.ts +33 -0
- package/dist/overlay/SceneOverlay.d.ts +68 -0
- package/dist/reader/Area.d.ts +63 -0
- package/dist/reader/Exit.d.ts +15 -0
- package/dist/reader/MapReader.d.ts +34 -0
- package/dist/reader/Plane.d.ts +33 -0
- package/dist/render/CanvasRenderer.d.ts +17 -0
- package/dist/render/RecordingLayer.d.ts +158 -0
- package/dist/render/SvgRenderer.d.ts +7 -0
- package/dist/render/shapeToRecording.d.ts +3 -0
- package/dist/rendering/KonvaRenderBackend.d.ts +122 -0
- package/dist/rendering/MapRenderer.d.ts +213 -0
- package/dist/rendering/SceneManager.d.ts +54 -0
- package/dist/scene/AmbientLightStyle.d.ts +29 -0
- package/dist/scene/GridStyle.d.ts +21 -0
- package/dist/scene/InnerExitStyle.d.ts +24 -0
- package/dist/scene/OverlayStyle.d.ts +47 -0
- package/dist/scene/RoomStyle.d.ts +32 -0
- package/dist/scene/Shape.d.ts +151 -0
- package/dist/scene/SpecialExitStyle.d.ts +37 -0
- package/dist/scene/StubStyle.d.ts +15 -0
- package/dist/scene/elements/ExitLayout.d.ts +22 -0
- package/dist/scene/elements/GridLayout.d.ts +24 -0
- package/dist/scene/elements/LabelLayout.d.ts +11 -0
- package/dist/scene/elements/OverlayLayout.d.ts +14 -0
- package/dist/scene/elements/RoomLayout.d.ts +19 -0
- package/dist/scene/elements/SpecialExitLayout.d.ts +19 -0
- package/dist/scene/elements/StubLayout.d.ts +19 -0
- package/dist/style/Style.d.ts +60 -0
- package/dist/style/applyStyle.d.ts +3 -0
- package/dist/style/index.d.ts +21 -0
- package/dist/style/shape/BlueprintStyle.d.ts +11 -0
- package/dist/style/shape/ConstructionStyle.d.ts +17 -0
- package/dist/style/shape/IsometricStyle.d.ts +32 -0
- package/dist/style/shape/NeonStyle.d.ts +17 -0
- package/dist/style/shape/ParchmentStyle.d.ts +13 -0
- package/dist/style/shape/SciFiStyle.d.ts +16 -0
- package/dist/style/shape/SketchyStyle.d.ts +22 -0
- package/dist/style/shape/index.d.ts +25 -0
- package/dist/style/shape/paintMap.d.ts +25 -0
- package/dist/style/shape/wobble.d.ts +24 -0
- package/{src/types/MapData.ts → dist/types/MapData.d.ts} +70 -90
- package/dist/types/Settings.d.ts +206 -0
- package/dist/utils/color.d.ts +12 -0
- package/dist/utils/textMeasure.d.ts +38 -0
- package/package.json +67 -37
- package/demo/colors.json +0 -1
- package/demo/index.html +0 -102
- package/demo/main.ts +0 -389
- package/demo/mapExport.json +0 -1
- package/demo/tsconfig.json +0 -11
- package/src/ExitRenderer.ts +0 -275
- package/src/PathFinder.ts +0 -93
- package/src/PathRenderer.ts +0 -129
- package/src/Renderer.ts +0 -374
- package/src/directions.ts +0 -66
- package/src/index.ts +0 -4
- package/src/reader/Area.ts +0 -96
- package/src/reader/Exit.ts +0 -36
- package/src/reader/ExplorationArea.ts +0 -132
- package/src/reader/MapReader.ts +0 -123
- package/src/reader/Plane.ts +0 -42
- package/tsconfig.json +0 -17
- package/vercel.json +0 -5
- package/vite.config.ts +0 -29
- package/vite.demo.config.ts +0 -15
package/demo/tsconfig.json
DELETED
package/src/ExitRenderer.ts
DELETED
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
import Exit, {longToShort} from "./reader/Exit";
|
|
2
|
-
import MapReader from "./reader/MapReader";
|
|
3
|
-
import Konva from "konva";
|
|
4
|
-
import {Settings} from "./Renderer";
|
|
5
|
-
import {movePoint} from "./directions";
|
|
6
|
-
|
|
7
|
-
const Colors = {
|
|
8
|
-
OPEN_DOOR: 'rgb(10, 155, 10)',
|
|
9
|
-
CLOSED_DOOR: 'rgb(226, 205, 59)',
|
|
10
|
-
LOCKED_DOOR: 'rgb(155, 10, 10)'
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const dirNumbers: Record<number, MapData.direction> = {
|
|
14
|
-
1: "north",
|
|
15
|
-
2: "northeast",
|
|
16
|
-
3: "northwest",
|
|
17
|
-
4: "east",
|
|
18
|
-
5: "west",
|
|
19
|
-
6: "south",
|
|
20
|
-
7: "southeast",
|
|
21
|
-
8: "southwest",
|
|
22
|
-
9: "up",
|
|
23
|
-
10: "down",
|
|
24
|
-
11: "in",
|
|
25
|
-
12: "out",
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const innerExits: MapData.direction[] = ["up", "down", "in", "out"];
|
|
29
|
-
|
|
30
|
-
function getDoorColor(doorType: 1 | 2 | 3) {
|
|
31
|
-
switch (doorType) {
|
|
32
|
-
case 1:
|
|
33
|
-
return Colors.OPEN_DOOR
|
|
34
|
-
case 2:
|
|
35
|
-
return Colors.CLOSED_DOOR
|
|
36
|
-
default:
|
|
37
|
-
return Colors.LOCKED_DOOR
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export default class ExitRenderer {
|
|
42
|
-
|
|
43
|
-
private mapReader: MapReader;
|
|
44
|
-
|
|
45
|
-
constructor(mapReader: MapReader) {
|
|
46
|
-
this.mapReader = mapReader;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
render(exit: Exit) {
|
|
50
|
-
if (exit.aDir && exit.bDir) {
|
|
51
|
-
return this.renderTwoWayExit(exit);
|
|
52
|
-
} else {
|
|
53
|
-
return this.renderOneWayExit(exit);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
private renderTwoWayExit(exit: Exit) {
|
|
58
|
-
const sourceRoom = this.mapReader.getRoom(exit.a)
|
|
59
|
-
const targetRoom = this.mapReader.getRoom(exit.b);
|
|
60
|
-
|
|
61
|
-
if (!sourceRoom || !targetRoom || !exit.aDir || !exit.bDir) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const exitRender = new Konva.Group();
|
|
66
|
-
|
|
67
|
-
const points = []
|
|
68
|
-
points.push(...Object.values(movePoint(sourceRoom.x, sourceRoom.y, exit.aDir, Settings.roomSize / 2)));
|
|
69
|
-
points.push(...Object.values(movePoint(targetRoom.x, targetRoom.y, exit.bDir, Settings.roomSize / 2)));
|
|
70
|
-
|
|
71
|
-
if (sourceRoom.doors[longToShort[exit.aDir]] || targetRoom.doors[longToShort[exit.bDir]]) {
|
|
72
|
-
const door = this.renderDoor(points, sourceRoom.doors[longToShort[exit.aDir]] ?? targetRoom.doors[longToShort[exit.bDir]])
|
|
73
|
-
exitRender.add(door);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const link = new Konva.Line({
|
|
77
|
-
points,
|
|
78
|
-
stroke: Settings.lineColor,
|
|
79
|
-
strokeWidth: 0.025,
|
|
80
|
-
});
|
|
81
|
-
exitRender.add(link);
|
|
82
|
-
|
|
83
|
-
return exitRender;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
private renderOneWayExit(exit: Exit) {
|
|
87
|
-
const sourceRoom = exit.aDir ? this.mapReader.getRoom(exit.a) : this.mapReader.getRoom(exit.b)
|
|
88
|
-
const targetRoom = exit.aDir ? this.mapReader.getRoom(exit.b) : this.mapReader.getRoom(exit.a)
|
|
89
|
-
const dir = exit.aDir ? exit.aDir : exit.bDir;
|
|
90
|
-
|
|
91
|
-
if (!sourceRoom || !targetRoom) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
if (sourceRoom.area != targetRoom.area && dir) {
|
|
96
|
-
return this.renderAreaExit(sourceRoom, dir);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
let targetPoint = {x: targetRoom.x, y: targetRoom.y};
|
|
100
|
-
if (targetRoom.area !== sourceRoom.area || targetRoom.z !== sourceRoom.z) {
|
|
101
|
-
targetPoint = movePoint(sourceRoom.x, sourceRoom.y, dir, Settings.roomSize / 2);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const startPoint = movePoint(sourceRoom.x, sourceRoom.y, dir, 0.3);
|
|
105
|
-
|
|
106
|
-
const middlePointX = startPoint.x - (startPoint.x - targetPoint.x) / 2;
|
|
107
|
-
const middlePointY = startPoint.y - (startPoint.y - targetPoint.y) / 2;
|
|
108
|
-
|
|
109
|
-
const group = new Konva.Group();
|
|
110
|
-
const points = []
|
|
111
|
-
points.push(...Object.values(movePoint(sourceRoom.x, sourceRoom.y, dir, Settings.roomSize / 2)));
|
|
112
|
-
points.push(targetPoint.x, targetPoint.y);
|
|
113
|
-
const link = new Konva.Line({
|
|
114
|
-
points,
|
|
115
|
-
stroke: Settings.lineColor,
|
|
116
|
-
strokeWidth: 0.025,
|
|
117
|
-
dashEnabled: true,
|
|
118
|
-
dash: [0.1, 0.05],
|
|
119
|
-
});
|
|
120
|
-
group.add(link)
|
|
121
|
-
|
|
122
|
-
const arrow = new Konva.Arrow({
|
|
123
|
-
points: [points[0], points[1], middlePointX, middlePointY],
|
|
124
|
-
pointerLength: 0.5,
|
|
125
|
-
pointerWidth: 0.35,
|
|
126
|
-
strokeWidth: 0.035,
|
|
127
|
-
stroke: Settings.lineColor,
|
|
128
|
-
fill: '#FF0000',
|
|
129
|
-
dashEnabled: true,
|
|
130
|
-
dash: [0.1, 0.05],
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
group.add(arrow)
|
|
134
|
-
|
|
135
|
-
return group;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
renderAreaExit(room: MapData.Room, dir: MapData.direction) {
|
|
139
|
-
const start = movePoint(room.x, room.y, dir, Settings.roomSize / 2)
|
|
140
|
-
const end = movePoint(room.x, room.y, dir, Settings.roomSize * 1.5)
|
|
141
|
-
return new Konva.Arrow({
|
|
142
|
-
points: [start.x, start.y, end.x, end.y],
|
|
143
|
-
pointerLength: 0.3,
|
|
144
|
-
pointerWidth: 0.3,
|
|
145
|
-
strokeWidth: 0.035,
|
|
146
|
-
stroke: this.mapReader.getColorValue(room.env),
|
|
147
|
-
fill: this.mapReader.getColorValue(room.env),
|
|
148
|
-
})
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
renderSpecialExits(room: MapData.Room) {
|
|
152
|
-
return Object.entries(room.customLines).map(([_, line]) => {
|
|
153
|
-
const points = [room.x, room.y]
|
|
154
|
-
line.points.reduce((acc, point) => {
|
|
155
|
-
acc.push(point.x, -point.y);
|
|
156
|
-
return acc;
|
|
157
|
-
}, points)
|
|
158
|
-
|
|
159
|
-
const construct = line.attributes.arrow ? Konva.Arrow : Konva.Line;
|
|
160
|
-
const lineRender = new construct({
|
|
161
|
-
points: points,
|
|
162
|
-
strokeWidth: .025,
|
|
163
|
-
stroke: `rgb(${line.attributes.color.r}, ${line.attributes.color.g}, ${line.attributes.color.b})`,
|
|
164
|
-
fill: `rgb(${line.attributes.color.r}, ${line.attributes.color.g} , ${line.attributes.color.b})`,
|
|
165
|
-
pointerLength: 0.3,
|
|
166
|
-
pointerWidth: 0.2,
|
|
167
|
-
|
|
168
|
-
})
|
|
169
|
-
|
|
170
|
-
let style = line.attributes.style;
|
|
171
|
-
if (style === "dot line") {
|
|
172
|
-
lineRender.dash([0.05, 0.05])
|
|
173
|
-
lineRender.dashOffset(0.1)
|
|
174
|
-
} else if (style === "dash line") {
|
|
175
|
-
lineRender.dash([0.4, 0.2])
|
|
176
|
-
} else if (style === "solid line") {
|
|
177
|
-
} else if (style !== undefined) {
|
|
178
|
-
console.log("Brak opisu stylu: " + style);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return lineRender;
|
|
182
|
-
})
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
renderStubs(room: MapData.Room) {
|
|
186
|
-
return room.stubs.map(stub => {
|
|
187
|
-
const direction = dirNumbers[stub];
|
|
188
|
-
const start = movePoint(room.x, room.y, direction, Settings.roomSize / 2)
|
|
189
|
-
const end = movePoint(room.x, room.y, direction, Settings.roomSize / 2 + 0.5)
|
|
190
|
-
const points = [start.x, start.y, end.x, end.y]
|
|
191
|
-
return new Konva.Line({
|
|
192
|
-
points,
|
|
193
|
-
stroke: Settings.lineColor,
|
|
194
|
-
strokeWidth: 0.025,
|
|
195
|
-
});
|
|
196
|
-
})
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
renderInnerExits(room: MapData.Room) {
|
|
200
|
-
return innerExits.map(exit => {
|
|
201
|
-
if (room.exits[exit]) {
|
|
202
|
-
const render = new Konva.Group();
|
|
203
|
-
const triangle = new Konva.RegularPolygon({
|
|
204
|
-
x: room.x,
|
|
205
|
-
y: room.y,
|
|
206
|
-
sides: 3,
|
|
207
|
-
fill: this.mapReader.getSymbolColor(room.env, 0.6),
|
|
208
|
-
stroke: this.mapReader.getSymbolColor(room.env),
|
|
209
|
-
strokeWidth: 0.025,
|
|
210
|
-
radius: Settings.roomSize / 5,
|
|
211
|
-
scaleX: 1.4,
|
|
212
|
-
scaleY: 0.8
|
|
213
|
-
})
|
|
214
|
-
render.add(triangle);
|
|
215
|
-
|
|
216
|
-
let doorType = room.doors[exit];
|
|
217
|
-
if (doorType !== undefined) {
|
|
218
|
-
switch (doorType) {
|
|
219
|
-
case 1:
|
|
220
|
-
triangle.stroke(Colors.OPEN_DOOR)
|
|
221
|
-
break;
|
|
222
|
-
case 2:
|
|
223
|
-
triangle.stroke(Colors.CLOSED_DOOR);
|
|
224
|
-
break;
|
|
225
|
-
default:
|
|
226
|
-
triangle.stroke(Colors.LOCKED_DOOR);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
switch (exit) {
|
|
231
|
-
case "up":
|
|
232
|
-
triangle.position(movePoint(room.x, room.y, "south", Settings.roomSize / 4));
|
|
233
|
-
break;
|
|
234
|
-
case "down":
|
|
235
|
-
triangle.rotation(180);
|
|
236
|
-
triangle.position(movePoint(room.x, room.y, "north", Settings.roomSize / 4));
|
|
237
|
-
break;
|
|
238
|
-
case "in":
|
|
239
|
-
const inRender = triangle.clone()
|
|
240
|
-
inRender.rotation(-90);
|
|
241
|
-
inRender.position(movePoint(room.x, room.y, "east", Settings.roomSize / 4));
|
|
242
|
-
render.add(inRender);
|
|
243
|
-
triangle.rotation(90);
|
|
244
|
-
triangle.position(movePoint(room.x, room.y, "west", Settings.roomSize / 4));
|
|
245
|
-
break;
|
|
246
|
-
case "out":
|
|
247
|
-
const outRender = triangle.clone()
|
|
248
|
-
outRender.rotation(90);
|
|
249
|
-
outRender.position(movePoint(room.x, room.y, "east", Settings.roomSize / 4));
|
|
250
|
-
render.add(outRender);
|
|
251
|
-
triangle.rotation(-90);
|
|
252
|
-
triangle.position(movePoint(room.x, room.y, "west", Settings.roomSize / 4));
|
|
253
|
-
break;
|
|
254
|
-
}
|
|
255
|
-
return render
|
|
256
|
-
}
|
|
257
|
-
}).filter(e => e !== undefined)
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
renderDoor(points: number[], type: 1 | 2 | 3) {
|
|
261
|
-
const point = {
|
|
262
|
-
x: points[0] + (points[2] - points[0]) / 2,
|
|
263
|
-
y: points[1] + (points[3] - points[1]) / 2,
|
|
264
|
-
}
|
|
265
|
-
return new Konva.Rect({
|
|
266
|
-
x: point.x - Settings.roomSize / 4,
|
|
267
|
-
y: point.y - Settings.roomSize / 4,
|
|
268
|
-
width: Settings.roomSize / 2,
|
|
269
|
-
height: Settings.roomSize / 2,
|
|
270
|
-
stroke: getDoorColor(type),
|
|
271
|
-
strokeWidth: 0.025
|
|
272
|
-
})
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
}
|
package/src/PathFinder.ts
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import Graph from "node-dijkstra";
|
|
2
|
-
import MapReader from "./reader/MapReader";
|
|
3
|
-
|
|
4
|
-
const exitNumberToDirection: Record<number, MapData.direction> = {
|
|
5
|
-
1: "north",
|
|
6
|
-
2: "northeast",
|
|
7
|
-
3: "northwest",
|
|
8
|
-
4: "east",
|
|
9
|
-
5: "west",
|
|
10
|
-
6: "south",
|
|
11
|
-
7: "southeast",
|
|
12
|
-
8: "southwest",
|
|
13
|
-
9: "up",
|
|
14
|
-
10: "down",
|
|
15
|
-
11: "in",
|
|
16
|
-
12: "out",
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
type GraphDefinition = Record<string, Record<string, number>>;
|
|
20
|
-
|
|
21
|
-
export default class PathFinder {
|
|
22
|
-
|
|
23
|
-
private readonly mapReader: MapReader;
|
|
24
|
-
private readonly graph: Graph;
|
|
25
|
-
private readonly cache = new Map<string, Array<number> | null>();
|
|
26
|
-
|
|
27
|
-
constructor(mapReader: MapReader) {
|
|
28
|
-
this.mapReader = mapReader;
|
|
29
|
-
this.graph = this.buildGraph();
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
private buildGraph(): Graph {
|
|
33
|
-
const graphDefinition: GraphDefinition = {};
|
|
34
|
-
this.mapReader.getRooms().forEach(room => {
|
|
35
|
-
const connections: Record<string, number> = {};
|
|
36
|
-
|
|
37
|
-
const lockedDirections = new Set(
|
|
38
|
-
(room.exitLocks ?? [])
|
|
39
|
-
.map(lockId => exitNumberToDirection[lockId])
|
|
40
|
-
.filter((direction): direction is MapData.direction => Boolean(direction))
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
const lockedSpecialTargets = new Set(room.mSpecialExitLocks ?? []);
|
|
44
|
-
|
|
45
|
-
Object.entries(room.exits ?? {}).forEach(([direction, targetRoomId]) => {
|
|
46
|
-
if (lockedDirections.has(direction as MapData.direction)) {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
if (this.mapReader.getRoom(targetRoomId)) {
|
|
50
|
-
connections[targetRoomId.toString()] = 1;
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
Object.values(room.specialExits ?? {}).forEach(targetRoomId => {
|
|
55
|
-
if (lockedSpecialTargets.has(targetRoomId)) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
if (this.mapReader.getRoom(targetRoomId)) {
|
|
59
|
-
connections[targetRoomId.toString()] = 1;
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
graphDefinition[room.id.toString()] = connections;
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
return new Graph(graphDefinition);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
findPath(from: number, to: number): Array<number> | null {
|
|
70
|
-
const cacheKey = `${from}->${to}`;
|
|
71
|
-
if (this.cache.has(cacheKey)) {
|
|
72
|
-
return this.cache.get(cacheKey)!;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (from === to) {
|
|
76
|
-
const result = this.mapReader.getRoom(from) ? [from] : null;
|
|
77
|
-
this.cache.set(cacheKey, result);
|
|
78
|
-
return result;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (!this.mapReader.getRoom(from) || !this.mapReader.getRoom(to)) {
|
|
82
|
-
this.cache.set(cacheKey, null);
|
|
83
|
-
return null;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const path = this.graph.path(from.toString(), to.toString());
|
|
87
|
-
const nodes = Array.isArray(path) ? path : path?.path;
|
|
88
|
-
const result = nodes ? nodes.map((id: string) => Number(id)) : null;
|
|
89
|
-
this.cache.set(cacheKey, result);
|
|
90
|
-
return result;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
package/src/PathRenderer.ts
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import Konva from "konva";
|
|
2
|
-
import MapReader from "./reader/MapReader";
|
|
3
|
-
import {Settings} from "./Renderer";
|
|
4
|
-
import {movePoint, PlanarDirection, planarDirections, oppositeDirections} from "./directions";
|
|
5
|
-
|
|
6
|
-
export default class PathRenderer {
|
|
7
|
-
private readonly mapReader: MapReader;
|
|
8
|
-
private readonly overlayLayer: Konva.Layer;
|
|
9
|
-
private paths: Konva.Line[] = [];
|
|
10
|
-
|
|
11
|
-
constructor(mapReader: MapReader, overlayLayer: Konva.Layer) {
|
|
12
|
-
this.mapReader = mapReader;
|
|
13
|
-
this.overlayLayer = overlayLayer;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
renderPath(locations: number[], currentArea?: number, currentZIndex?: number) {
|
|
17
|
-
if (currentArea === undefined || currentZIndex === undefined) {
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const rooms = locations
|
|
22
|
-
.map(location => this.mapReader.getRoom(location))
|
|
23
|
-
.filter((room): room is MapData.Room => room !== undefined);
|
|
24
|
-
|
|
25
|
-
const segments: number[][] = [];
|
|
26
|
-
let currentSegment: number[] | null = null;
|
|
27
|
-
|
|
28
|
-
const finalizeSegment = () => {
|
|
29
|
-
if (!currentSegment) {
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
if (currentSegment.length < 4) {
|
|
33
|
-
segments.pop();
|
|
34
|
-
}
|
|
35
|
-
currentSegment = null;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
const ensureSegment = () => {
|
|
39
|
-
if (!currentSegment) {
|
|
40
|
-
currentSegment = [];
|
|
41
|
-
segments.push(currentSegment);
|
|
42
|
-
}
|
|
43
|
-
return currentSegment;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
rooms.forEach((room, index) => {
|
|
47
|
-
if (!this.isRoomVisible(room, currentArea, currentZIndex)) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const previousRoom = index > 0 ? rooms[index - 1] : undefined;
|
|
52
|
-
const nextRoom = index < rooms.length - 1 ? rooms[index + 1] : undefined;
|
|
53
|
-
const previousVisible = this.isRoomVisible(previousRoom, currentArea, currentZIndex);
|
|
54
|
-
|
|
55
|
-
if (!previousVisible) {
|
|
56
|
-
finalizeSegment();
|
|
57
|
-
const segment = ensureSegment();
|
|
58
|
-
if (previousRoom) {
|
|
59
|
-
const directionToPrevious = this.getDirectionTowards(room, previousRoom);
|
|
60
|
-
if (directionToPrevious) {
|
|
61
|
-
const startPoint = movePoint(room.x, room.y, directionToPrevious, Settings.roomSize);
|
|
62
|
-
segment.push(startPoint.x, startPoint.y);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
} else {
|
|
66
|
-
ensureSegment();
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
currentSegment?.push(room.x, room.y);
|
|
70
|
-
|
|
71
|
-
const nextVisible = this.isRoomVisible(nextRoom, currentArea, currentZIndex);
|
|
72
|
-
if (!nextVisible && nextRoom) {
|
|
73
|
-
const directionToNext = this.getDirectionTowards(room, nextRoom);
|
|
74
|
-
if (directionToNext) {
|
|
75
|
-
const endPoint = movePoint(room.x, room.y, directionToNext, Settings.roomSize);
|
|
76
|
-
currentSegment?.push(endPoint.x, endPoint.y);
|
|
77
|
-
}
|
|
78
|
-
finalizeSegment();
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
finalizeSegment();
|
|
83
|
-
|
|
84
|
-
const paths = segments
|
|
85
|
-
.filter(points => points.length >= 4)
|
|
86
|
-
.map(points => new Konva.Line({
|
|
87
|
-
points,
|
|
88
|
-
stroke: 'green',
|
|
89
|
-
strokeWidth: 0.1
|
|
90
|
-
}));
|
|
91
|
-
|
|
92
|
-
paths.forEach(path => {
|
|
93
|
-
this.overlayLayer.add(path);
|
|
94
|
-
this.paths.push(path);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
return paths[0];
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
clearPaths() {
|
|
101
|
-
this.paths.forEach(path => {
|
|
102
|
-
path.destroy();
|
|
103
|
-
});
|
|
104
|
-
this.paths = [];
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
private isRoomVisible(room: MapData.Room | undefined, currentArea: number | undefined, currentZIndex: number | undefined) {
|
|
108
|
-
if (!room) {
|
|
109
|
-
return false;
|
|
110
|
-
}
|
|
111
|
-
return room.area === currentArea && room.z === currentZIndex;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
private getDirectionTowards(from: MapData.Room, to: MapData.Room): PlanarDirection | undefined {
|
|
115
|
-
for (const direction of planarDirections) {
|
|
116
|
-
if (from.exits[direction] === to.id) {
|
|
117
|
-
return direction;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
for (const direction of planarDirections) {
|
|
122
|
-
if (to.exits[direction] === from.id) {
|
|
123
|
-
return oppositeDirections[direction];
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return undefined;
|
|
128
|
-
}
|
|
129
|
-
}
|