mudlet-map-renderer 0.8.6-konva → 0.9.1-konva
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/Renderer.d.ts +24 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +405 -218
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/Renderer.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { default as MapReader } from './reader/MapReader';
|
|
2
2
|
import { default as Area } from './reader/Area';
|
|
3
3
|
export type LabelRenderMode = "image" | "data";
|
|
4
|
+
export type CullingMode = "none" | "basic" | "indexed";
|
|
4
5
|
export type RoomContextMenuEventDetail = {
|
|
5
6
|
roomId: number;
|
|
6
7
|
position: {
|
|
@@ -17,6 +18,7 @@ export declare class Settings {
|
|
|
17
18
|
static instantMapMove: boolean;
|
|
18
19
|
static highlightCurrentRoom: boolean;
|
|
19
20
|
static cullingEnabled: boolean;
|
|
21
|
+
static cullingMode: CullingMode;
|
|
20
22
|
static cullingBounds: {
|
|
21
23
|
x: number;
|
|
22
24
|
y: number;
|
|
@@ -25,6 +27,7 @@ export declare class Settings {
|
|
|
25
27
|
} | null;
|
|
26
28
|
static labelRenderMode: LabelRenderMode;
|
|
27
29
|
static transparentLabels: boolean;
|
|
30
|
+
static cullingDebug: boolean;
|
|
28
31
|
}
|
|
29
32
|
export declare class Renderer {
|
|
30
33
|
private readonly stage;
|
|
@@ -32,6 +35,7 @@ export declare class Renderer {
|
|
|
32
35
|
private readonly linkLayer;
|
|
33
36
|
private readonly overlayLayer;
|
|
34
37
|
private readonly positionLayer;
|
|
38
|
+
private readonly debugLayer;
|
|
35
39
|
private mapReader;
|
|
36
40
|
private exitRenderer;
|
|
37
41
|
private pathRenderer;
|
|
@@ -47,15 +51,34 @@ export declare class Renderer {
|
|
|
47
51
|
private currentRoomOverlay;
|
|
48
52
|
private roomNodes;
|
|
49
53
|
private standaloneExitNodes;
|
|
54
|
+
private spatialBucketSize;
|
|
55
|
+
private roomSpatialIndex;
|
|
56
|
+
private exitSpatialIndex;
|
|
57
|
+
private visibleRooms;
|
|
58
|
+
private visibleStandaloneExitNodes;
|
|
50
59
|
private cullingScheduled;
|
|
60
|
+
private cullingViewportDebug?;
|
|
61
|
+
private cullingSearchDebug?;
|
|
62
|
+
private cullingBucketDebug;
|
|
51
63
|
constructor(container: HTMLDivElement, mapReader: MapReader);
|
|
52
64
|
private onResize;
|
|
53
65
|
private initScaling;
|
|
54
66
|
drawArea(id: number, zIndex: number): void;
|
|
67
|
+
private computeSpatialBucketSize;
|
|
68
|
+
private getBucketKey;
|
|
69
|
+
private forEachBucket;
|
|
70
|
+
private addRoomToSpatialIndex;
|
|
71
|
+
private addStandaloneExitToSpatialIndex;
|
|
72
|
+
private collectRoomCandidates;
|
|
73
|
+
private collectStandaloneExitCandidates;
|
|
74
|
+
private getBucketBounds;
|
|
55
75
|
private emitRoomContextEvent;
|
|
56
76
|
private emitZoomChangeEvent;
|
|
57
77
|
setZoom(zoom: number): boolean;
|
|
58
78
|
getZoom(): number;
|
|
79
|
+
setCullingMode(mode: CullingMode): void;
|
|
80
|
+
getCullingMode(): CullingMode;
|
|
81
|
+
setCullingDebug(enabled: boolean): void;
|
|
59
82
|
getCurrentArea(): Area | undefined;
|
|
60
83
|
setPosition(roomId: number): void;
|
|
61
84
|
renderPath(locations: number[], color?: string): import('konva/lib/shapes/Line').Line<{
|
|
@@ -72,6 +95,7 @@ export declare class Renderer {
|
|
|
72
95
|
private renderRooms;
|
|
73
96
|
private scheduleRoomCulling;
|
|
74
97
|
private updateRoomCulling;
|
|
98
|
+
private updateCullingDebugVisuals;
|
|
75
99
|
private clearCurrentRoomOverlay;
|
|
76
100
|
private updateCurrentRoomOverlay;
|
|
77
101
|
private createOverlayRoomGroup;
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("konva"),Y=["north","south","east","west","northeast","northwest","southeast","southwest"],D={north:"n",south:"s",east:"e",west:"w",northeast:"ne",northwest:"nw",southeast:"se",southwest:"sw",up:"u",down:"d",in:"i",out:"o"},F={north:{x:0,y:-1},south:{x:0,y:1},east:{x:1,y:0},west:{x:-1,y:0},northeast:{x:1,y:-1},northwest:{x:-1,y:-1},southeast:{x:1,y:1},southwest:{x:-1,y:1}},X=["north","south","east","west","northeast","northwest","southeast","southwest"],Q={north:"south",south:"north",east:"west",west:"east",northeast:"southwest",northwest:"southeast",southeast:"northwest",southwest:"northeast"};function U(d){return d?Object.prototype.hasOwnProperty.call(F,d):!1}function x(d,t,e,s=1){if(!U(e))return{x:d,y:t};const i=F[e];return{x:d+i.x*s,y:t+i.y*s}}const L={OPEN_DOOR:"rgb(10, 155, 10)",CLOSED_DOOR:"rgb(226, 205, 59)",LOCKED_DOOR:"rgb(155, 10, 10)",ONE_WAY_FILL:"rgb(155, 10, 10)"},J={1:"north",2:"northeast",3:"northwest",4:"east",5:"west",6:"south",7:"southeast",8:"southwest",9:"up",10:"down",11:"in",12:"out"},tt=["up","down","in","out"];function et(d){switch(d){case 1:return L.OPEN_DOOR;case 2:return L.CLOSED_DOOR;default:return L.LOCKED_DOOR}}class st{constructor(t,e){this.mapReader=t,this.mapRenderer=e}render(t,e){return this.renderWithColor(t,h.lineColor,e)}renderWithColor(t,e,s){return t.aDir&&t.bDir?this.renderTwoWayExit(t,e,s):this.renderOneWayExit(t,e)}renderTwoWayExit(t,e,s){const i=this.mapReader.getRoom(t.a),r=this.mapReader.getRoom(t.b);if(!i||!r||!t.aDir||!t.bDir||!Y.includes(t.aDir)||!Y.includes(t.bDir)||i.customLines[D[t.aDir]]&&r.customLines[D[t.bDir]]||i.z!==r.z&&(s!==r.z&&i.customLines[D[t.aDir]]||s!==i.z&&r.customLines[D[t.bDir]]))return;const n=new f.Group,o=[];if(o.push(...Object.values(x(i.x,i.y,t.aDir,h.roomSize/2))),o.push(...Object.values(x(r.x,r.y,t.bDir,h.roomSize/2))),i.doors[D[t.aDir]]||r.doors[D[t.bDir]]){const u=this.renderDoor(o,i.doors[D[t.aDir]]??r.doors[D[t.bDir]]);n.add(u)}const a=new f.Line({points:o,stroke:e,strokeWidth:.025});return n.add(a),n}renderOneWayExit(t,e){const s=t.aDir?this.mapReader.getRoom(t.a):this.mapReader.getRoom(t.b),i=t.aDir?this.mapReader.getRoom(t.b):this.mapReader.getRoom(t.a),r=t.aDir?t.aDir:t.bDir;if(!r||!s||!i||s.customLines[D[r]||r])return;if(s.area!=i.area&&r)return this.renderAreaExit(s,r,e);let n={x:i.x,y:i.y};(i.area!==s.area||i.z!==s.z)&&(n=x(s.x,s.y,r,h.roomSize/2));const o=x(s.x,s.y,r,.3),a=o.x-(o.x-n.x)/2,u=o.y-(o.y-n.y)/2,g=new f.Group,c=[];c.push(...Object.values(x(s.x,s.y,r,h.roomSize/2))),c.push(n.x,n.y);const l=new f.Line({points:c,stroke:e,strokeWidth:.025,dashEnabled:!0,dash:[.1,.05]});g.add(l);const m=new f.Arrow({points:[c[0],c[1],a,u],pointerLength:.5,pointerWidth:.35,strokeWidth:.035,stroke:e,fill:L.ONE_WAY_FILL,dashEnabled:!0,dash:[.1,.05]});return g.add(m),g}renderAreaExit(t,e,s){const i=x(t.x,t.y,e,h.roomSize/2),r=x(t.x,t.y,e,h.roomSize*1.5),n=s??this.mapReader.getColorValue(t.env);return new f.Arrow({points:[i.x,i.y,r.x,r.y],pointerLength:.3,pointerWidth:.3,strokeWidth:.035,stroke:n,fill:n})}renderSpecialExits(t,e){return Object.entries(t.customLines).map(([s,i])=>{const r=[t.x,t.y];i.points.reduce((g,c)=>(g.push(c.x,-c.y),g),r);const n=i.attributes.arrow?f.Arrow:f.Line,o=e??`rgb(${i.attributes.color.r}, ${i.attributes.color.g}, ${i.attributes.color.b})`,a=new n({points:r,strokeWidth:.025,stroke:o,fill:e??`rgb(${i.attributes.color.r}, ${i.attributes.color.g} , ${i.attributes.color.b})`,pointerLength:.3,pointerWidth:.2});let u=i.attributes.style;return u==="dot line"?(a.dash([.05,.05]),a.dashOffset(.1)):u==="dash line"?a.dash([.4,.2]):u==="solid line"||u!==void 0&&console.log("Brak opisu stylu: "+u),a})}renderStubs(t,e=h.lineColor){return t.stubs.map(s=>{const i=J[s],r=x(t.x,t.y,i,h.roomSize/2),n=x(t.x,t.y,i,h.roomSize/2+.5),o=[r.x,r.y,n.x,n.y];return new f.Line({points:o,stroke:e,strokeWidth:.025})})}renderInnerExits(t){return tt.map(e=>{if(t.exits[e]){const s=new f.Group,i=new f.RegularPolygon({x:t.x,y:t.y,sides:3,fill:this.mapReader.getSymbolColor(t.env,.6),stroke:this.mapReader.getSymbolColor(t.env),strokeWidth:.025,radius:h.roomSize/5,scaleX:1.4,scaleY:.8});s.add(i);let r=t.doors[e];if(r!==void 0)switch(r){case 1:i.stroke(L.OPEN_DOOR);break;case 2:i.stroke(L.CLOSED_DOOR);break;default:i.stroke(L.LOCKED_DOOR)}switch(e){case"up":i.position(x(t.x,t.y,"south",h.roomSize/4));break;case"down":i.rotation(180),i.position(x(t.x,t.y,"north",h.roomSize/4));break;case"in":const n=i.clone();n.rotation(-90),n.position(x(t.x,t.y,"east",h.roomSize/4)),s.add(n),i.rotation(90),i.position(x(t.x,t.y,"west",h.roomSize/4));break;case"out":const o=i.clone();o.rotation(90),o.position(x(t.x,t.y,"east",h.roomSize/4)),s.add(o),i.rotation(-90),i.position(x(t.x,t.y,"west",h.roomSize/4));break}return s}}).filter(e=>e!==void 0)}renderDoor(t,e){const s={x:t[0]+(t[2]-t[0])/2,y:t[1]+(t[3]-t[1])/2};return new f.Rect({x:s.x-h.roomSize/4,y:s.y-h.roomSize/4,width:h.roomSize/2,height:h.roomSize/2,stroke:et(e),strokeWidth:.025})}}class G{constructor(t,e){this.rooms=[],this.labels=[],this.rooms=t,this.bounds=this.createBounds(),this.labels=e}getRooms(){return this.rooms}getLabels(){return this.labels}getBounds(){return this.bounds}createBounds(){return this.rooms.reduce((t,e)=>({minX:Math.min(t.minX,e.x),maxX:Math.max(t.maxX,e.x),minY:Math.min(t.minY,e.y),maxY:Math.max(t.maxY,e.y)}),{minX:Number.POSITIVE_INFINITY,maxX:Number.NEGATIVE_INFINITY,minY:Number.POSITIVE_INFINITY,maxY:Number.NEGATIVE_INFINITY})}}class A{constructor(t){this.planes={},this.exits=new Map,this.version=0,this.area=t,this.planes=this.createPlanes(),this.createExits()}getAreaName(){return this.area.areaName}getAreaId(){return parseInt(this.area.areaId)}getVersion(){return this.version}markDirty(){this.version++}getPlane(t){return this.planes[t]}getPlanes(){return Object.values(this.planes)}getRooms(){return this.area.rooms}getLinkExits(t){return Array.from(this.exits.values()).filter(e=>e.zIndex.includes(t))}createPlanes(){const t=this.area.rooms.reduce((e,s)=>(e[s.z]||(e[s.z]=[]),e[s.z].push(s),e),{});return Object.entries(t).reduce((e,[s,i])=>(e[+s]=new G(i,this.area.labels.filter(r=>r.Z===+s)),e),{})}createExits(){this.area.rooms.forEach(t=>{Object.entries(t.specialExits).forEach(([e,s])=>this.createHalfExit(t.id,s,t.z,e)),Object.entries(t.exits).forEach(([e,s])=>this.createHalfExit(t.id,s,t.z,e))})}createHalfExit(t,e,s,i){if(t===e)return;const r=Math.min(t,e),n=Math.max(t,e),o=`${r}-${n}`;let a=this.exits.get(o);a||(a={a:r,b:n,zIndex:[s]}),r==t?a.aDir=i:a.bDir=i,a.zIndex.push(s),this.exits.set(o,a)}}class W extends G{constructor(t,e){super(t.getRooms(),t.getLabels()),this.basePlane=t,this.visitedRooms=e}getRooms(){return this.basePlane.getRooms().filter(t=>this.visitedRooms.has(t.id))}getLabels(){return this.basePlane.getLabels()}getBounds(){const t=this.getRooms();return t.length?t.reduce((e,s)=>({minX:Math.min(e.minX,s.x),maxX:Math.max(e.maxX,s.x),minY:Math.min(e.minY,s.y),maxY:Math.max(e.maxY,s.y)}),{minX:Number.POSITIVE_INFINITY,maxX:Number.NEGATIVE_INFINITY,minY:Number.POSITIVE_INFINITY,maxY:Number.NEGATIVE_INFINITY}):this.basePlane.getBounds()}}class z extends A{constructor(t,e){super(t),this.planeCache=new WeakMap,this.visitedRooms=e instanceof Set?e:new Set(e??[]),this.areaRoomIds=new Set(t.rooms.map(s=>s.id))}getPlane(t){const e=super.getPlane(t);if(!e)return e;let s=this.planeCache.get(e);return s||(s=new W(e,this.visitedRooms),this.planeCache.set(e,s)),s}getPlanes(){return super.getPlanes().map(t=>{let e=this.planeCache.get(t);return e||(e=new W(t,this.visitedRooms),this.planeCache.set(t,e)),e})}getLinkExits(t){return super.getLinkExits(t).filter(e=>this.visitedRooms.has(e.a)||this.visitedRooms.has(e.b))}getVisitedRoomCount(){return super.getRooms().reduce((t,e)=>t+(this.visitedRooms.has(e.id)?1:0),0)}getTotalRoomCount(){return this.areaRoomIds.size}hasVisitedRoom(t){return this.areaRoomIds.has(t)&&this.visitedRooms.has(t)}getVisitedRoomIds(){return super.getRooms().filter(t=>this.visitedRooms.has(t.id)).map(t=>t.id)}addVisitedRoom(t){const e=this.visitedRooms.has(t);this.visitedRooms.add(t);const s=!e&&this.areaRoomIds.has(t);return s&&this.markDirty(),s}addVisitedRooms(t){let e=0;for(const s of t){const i=this.visitedRooms.has(s);this.visitedRooms.add(s),!i&&this.areaRoomIds.has(s)&&e++}return e>0&&this.markDirty(),e}}class it{constructor(t,e){this.paths=[],this.mapReader=t,this.overlayLayer=e}renderPath(t,e,s,i="#66E64D"){if(e===void 0||s===void 0)return;const r=t.map(c=>this.mapReader.getRoom(c)).filter(c=>c!==void 0),n=[];let o=null;const a=()=>{o&&(o.length<4&&n.pop(),o=null)},u=()=>(o||(o=[],n.push(o)),o);r.forEach((c,l)=>{if(!this.isRoomVisible(c,e,s))return;const m=l>0?r[l-1]:void 0,R=l<r.length-1?r[l+1]:void 0;if(this.isRoomVisible(m,e,s))u();else{a();const b=u();if(m){const y=this.getDirectionTowards(c,m);if(y){const p=x(c.x,c.y,y,h.roomSize);b.push(p.x,p.y)}}}if(o==null||o.push(c.x,c.y),!this.isRoomVisible(R,e,s)&&R){const b=this.getDirectionTowards(c,R);if(b){const y=x(c.x,c.y,b,h.roomSize);o==null||o.push(y.x,y.y)}a()}}),a();const g=n.filter(c=>c.length>=4).map(c=>new f.Line({points:c,stroke:i,strokeWidth:.1}));return g.forEach(c=>{this.overlayLayer.add(c),this.paths.push(c)}),g[0]}clearPaths(){this.paths.forEach(t=>{t.destroy()}),this.paths=[]}isRoomVisible(t,e,s){return t?t.area===e&&t.z===s:!1}getDirectionTowards(t,e){for(const s of X)if(t.exits[s]===e.id)return s;for(const s of X)if(e.exits[s]===t.id)return Q[s]}}const B=.6,k=75,rt="rgb(225, 255, 225)",I="rgb(120, 72, 0)",C=class C{};C.roomSize=B,C.lineColor=rt,C.instantMapMove=!1,C.highlightCurrentRoom=!0,C.cullingEnabled=!0,C.cullingBounds=null,C.labelRenderMode="image";let h=C;class ot{constructor(t,e){this.highlights=new Map,this.currentZoom=1,this.currentRoomOverlay=[],this.roomNodes=new Map,this.standaloneExitNodes=[],this.cullingScheduled=!1,this.stage=new f.Stage({container:t,width:t.clientWidth,height:t.clientHeight,draggable:!0}),window.addEventListener("resize",()=>{this.onResize(t)}),t.addEventListener("resize",()=>{this.onResize(t)}),this.linkLayer=new f.Layer({listening:!1}),this.stage.add(this.linkLayer),this.roomLayer=new f.Layer,this.stage.add(this.roomLayer),this.overlayLayer=new f.Layer({listening:!1}),this.stage.add(this.overlayLayer),this.positionLayer=new f.Layer({listening:!1}),this.stage.add(this.positionLayer),this.mapReader=e,this.exitRenderer=new st(e,this),this.pathRenderer=new it(e,this.overlayLayer),this.initScaling(1.1),this.stage.on("dragmove",()=>this.scheduleRoomCulling()),this.stage.on("dragend",()=>this.scheduleRoomCulling())}onResize(t){this.stage.width(t.clientWidth),this.stage.height(t.clientHeight),this.currentRoomId&&this.centerOnRoom(this.mapReader.getRoom(this.currentRoomId),!1),this.stage.batchDraw(),this.scheduleRoomCulling()}initScaling(t){f.hitOnDragEnabled=!0;let e,s=!1,i=!1;this.stage.on("touchstart",r=>{const n=r.evt.touches;n&&n.length>1?(i=!0,this.stage.isDragging()&&(this.stage.stopDrag(),s=!0),this.stage.draggable(!1)):(i=!1,this.stage.draggable(!0))}),this.stage.on("touchend touchcancel",r=>{e=void 0;const n=r.evt.touches;(!n||n.length<=1)&&(i=!1,this.stage.draggable(!0))}),this.stage.on("wheel",r=>{r.evt.preventDefault();const n=this.stage.scaleX(),o=this.stage.getPointerPosition();if(!o)return;const a={x:(o.x-this.stage.x())/n,y:(o.y-this.stage.y())/n};let u=r.evt.deltaY>0?-1:1;r.evt.ctrlKey&&(u=-u);const g=u>0?this.currentZoom*t:this.currentZoom/t,c=g*k,l=this.setZoom(g),m={x:o.x-a.x*c,y:o.y-a.y*c};this.stage.position(m),this.scheduleRoomCulling(),l&&this.emitZoomChangeEvent()}),this.stage.on("touchmove",r=>{const n=r.evt.touches,o=n==null?void 0:n[0],a=n==null?void 0:n[1];if(a||i&&(i=!1,this.stage.draggable(!0)),o&&!a&&s&&!this.stage.isDragging()&&(this.stage.startDrag(),s=!1),!o||!a){e=void 0;return}r.evt.preventDefault(),this.stage.isDragging()&&(this.stage.stopDrag(),s=!0),i||(i=!0,this.stage.draggable(!1));const u=this.stage.container().getBoundingClientRect(),g={x:o.clientX-u.left,y:o.clientY-u.top},c={x:a.clientX-u.left,y:a.clientY-u.top},l=Math.hypot(g.x-c.x,g.y-c.y);if(e===void 0){e=l;return}if(e===0)return;const m=this.stage.scaleX(),R=this.stage.x(),v=this.stage.y(),E={x:this.stage.width()/2,y:this.stage.height()/2},b={x:(E.x-R)/m,y:(E.y-v)/m},y=this.currentZoom*(l/e),p=this.setZoom(y),w=this.stage.scaleX(),S={x:E.x-b.x*w,y:E.y-b.y*w};this.stage.position(S),this.stage.batchDraw(),this.scheduleRoomCulling(),e=l,p&&this.emitZoomChangeEvent()})}drawArea(t,e){const s=this.mapReader.getArea(t);if(!s)return;const i=s.getPlane(e);i&&(this.currentArea=t,this.currentAreaInstance=s,this.currentZIndex=e,this.currentAreaVersion=s.getVersion(),this.clearCurrentRoomOverlay(),this.roomLayer.destroyChildren(),this.linkLayer.destroyChildren(),this.roomNodes.clear(),this.standaloneExitNodes=[],this.stage.scale({x:k*this.currentZoom,y:k*this.currentZoom}),this.renderLabels(i.getLabels()),this.renderExits(s.getLinkExits(e)),this.renderRooms(i.getRooms()??[]),this.refreshHighlights(),this.stage.batchDraw(),this.scheduleRoomCulling())}emitRoomContextEvent(t,e,s){const i=this.stage.container(),r=i.getBoundingClientRect(),n={roomId:t,position:{x:e-r.left,y:s-r.top}},o=new CustomEvent("roomcontextmenu",{detail:n});i.dispatchEvent(o)}emitZoomChangeEvent(){const t=new CustomEvent("zoom",{detail:{zoom:this.currentZoom}});this.stage.container().dispatchEvent(t)}setZoom(t){return this.currentZoom===t?!1:(this.currentZoom=t,this.stage.scale({x:k*t,y:k*t}),this.scheduleRoomCulling(),!0)}getZoom(){return this.currentZoom}getCurrentArea(){return this.currentArea?this.mapReader.getArea(this.currentArea):void 0}setPosition(t){const e=this.mapReader.getRoom(t);if(!e)return;const s=this.mapReader.getArea(e.area),i=s==null?void 0:s.getVersion();let r=this.currentArea!==e.area||this.currentZIndex!==e.z;(this.currentArea!==e.area||this.currentZIndex!==e.z||i!==void 0&&this.currentAreaVersion!==i||s!==void 0&&this.currentAreaInstance!==s)&&this.drawArea(e.area,e.z),this.positionRender||(this.positionRender=new f.Circle({x:e.x,y:e.y,radius:B*.85,stroke:"rgb(0, 229, 178)",strokeWidth:.1,dash:[.05,.05],dashEnabled:!0}),this.positionLayer.add(this.positionRender)),this.centerOnRoom(e,r),this.updateCurrentRoomOverlay(e)}renderPath(t,e){return this.pathRenderer.renderPath(t,this.currentArea,this.currentZIndex,e)}clearPaths(){this.pathRenderer.clearPaths()}renderHighlight(t,e){const s=this.mapReader.getRoom(t);if(!s)return;const i=this.highlights.get(t);i!=null&&i.shape&&(i.shape.destroy(),delete i.shape);const r={color:e,area:s.area,z:s.z};if(this.highlights.set(t,r),s.area===this.currentArea&&s.z===this.currentZIndex){const n=this.createHighlightShape(s,e);return this.overlayLayer.add(n),r.shape=n,this.overlayLayer.batchDraw(),n}return r.shape}clearHighlights(){this.highlights.forEach(({shape:t})=>t==null?void 0:t.destroy()),this.highlights.clear(),this.overlayLayer.batchDraw()}refreshHighlights(){this.highlights.forEach((t,e)=>{var r;if((r=t.shape)==null||r.destroy(),delete t.shape,t.area!==this.currentArea||t.z!==this.currentZIndex)return;const s=this.mapReader.getRoom(e);if(!s)return;const i=this.createHighlightShape(s,t.color);this.overlayLayer.add(i),t.shape=i}),this.overlayLayer.batchDraw()}createHighlightShape(t,e){return new f.Circle({x:t.x,y:t.y,radius:h.roomSize*.9,stroke:e,strokeWidth:.15,dash:[.1,.05],dashEnabled:!0,listening:!1})}centerOnRoom(t,e=!1){var u;this.currentRoomId=t.id;const s={x:t.x,y:t.y};(u=this.positionRender)==null||u.position(t);const r=this.stage.getAbsoluteTransform().point(s),n={x:this.stage.width()/2,y:this.stage.height()/2},o=n.x-r.x,a=n.y-r.y;this.currentTransition&&(this.currentTransition.pause(),this.currentTransition.destroy(),delete this.currentTransition),e||h.instantMapMove?(this.stage.position({x:this.stage.x()+o,y:this.stage.y()+a}),this.scheduleRoomCulling()):(this.currentTransition=new f.Tween({node:this.stage,x:this.stage.x()+o,y:this.stage.y()+a,duration:.2,easing:f.Easings.EaseInOut,onUpdate:()=>this.scheduleRoomCulling(),onFinish:()=>this.scheduleRoomCulling()}),this.currentTransition.play())}renderRooms(t){t.forEach(e=>{const s=new f.Group({x:e.x-h.roomSize/2,y:e.y-h.roomSize/2}),i=new f.Rect({x:0,y:0,width:h.roomSize,height:h.roomSize,fill:this.mapReader.getColorValue(e.env),strokeWidth:.025,stroke:h.lineColor}),r=(l,m)=>this.emitRoomContextEvent(e.id,l,m);s.on("mouseenter",()=>{this.stage.container().style.cursor="pointer"}),s.on("mouseleave",()=>{this.stage.container().style.cursor="auto"}),s.on("contextmenu",l=>{l.evt.preventDefault();const m=l.evt;r(m.clientX,m.clientY)});let n,o,a;const u=()=>{a!==void 0&&(this.stage.draggable(a),a=void 0)},g=()=>{n!==void 0&&(window.clearTimeout(n),n=void 0),o=void 0,u()};s.on("touchstart",l=>{var R;if(g(),l.evt.touches&&l.evt.touches.length>1)return;const m=(R=l.evt.touches)==null?void 0:R[0];m&&(o={clientX:m.clientX,clientY:m.clientY},a=this.stage.draggable(),this.stage.draggable(!1),n=window.setTimeout(()=>{o&&r(o.clientX,o.clientY),g()},500))}),s.on("touchend",g),s.on("touchmove",l=>{var y;if(!o)return;const m=(y=l.evt.touches)==null?void 0:y[0];if(!m){g();return}const R=m.clientX-o.clientX,v=m.clientY-o.clientY,E=R*R+v*v,b=10;if(E>b*b){const p=a;g(),p&&this.stage.startDrag()}}),s.on("touchcancel",g),s.add(i),this.renderSymbol(e,s),this.roomLayer.add(s);const c=[];this.exitRenderer.renderSpecialExits(e).forEach(l=>{this.linkLayer.add(l),c.push(l)}),this.exitRenderer.renderStubs(e).forEach(l=>{this.linkLayer.add(l),c.push(l)}),this.exitRenderer.renderInnerExits(e).forEach(l=>{this.roomLayer.add(l)}),this.roomNodes.set(e.id,{room:e,group:s,linkNodes:c})})}scheduleRoomCulling(){this.cullingScheduled||(this.cullingScheduled=!0,window.requestAnimationFrame(()=>{this.cullingScheduled=!1,this.updateRoomCulling()}))}updateRoomCulling(){if(this.roomNodes.size===0&&this.standaloneExitNodes.length===0)return;const t=this.stage.scaleX();if(!t)return;const e=this.stage.position(),s=h.roomSize/2,i=h.cullingBounds,r=i?i.x:0,n=i?i.x+i.width:this.stage.width(),o=i?i.y:0,a=i?i.y+i.height:this.stage.height(),u=Math.min(r,n),g=Math.max(r,n),c=Math.min(o,a),l=Math.max(o,a),m=(u-e.x)/t,R=(g-e.x)/t,v=(c-e.y)/t,E=(l-e.y)/t;let b=!1,y=!1;if(!h.cullingEnabled){this.roomNodes.forEach(({group:p,linkNodes:w})=>{p.visible()||(p.visible(!0),b=!0),w.forEach(S=>{S.visible()||(S.visible(!0),y=!0)})}),this.standaloneExitNodes.forEach(p=>{p.visible()||(p.visible(!0),y=!0)}),b&&this.roomLayer.batchDraw(),y&&this.linkLayer.batchDraw();return}this.roomNodes.forEach(({room:p,group:w,linkNodes:S})=>{const P=p.x-s,V=p.x+s,N=p.y-s,O=p.y+s,M=V>=m&&P<=R&&O>=v&&N<=E;w.visible()!==M&&(w.visible(M),b=!0),S.forEach(T=>{T.visible()!==M&&(T.visible(M),y=!0)})}),this.standaloneExitNodes.forEach(p=>{const w=p.getClientRect({relativeTo:this.linkLayer}),S=w.x,P=w.x+w.width,V=w.y,N=w.y+w.height,O=P>=m&&S<=R&&N>=v&&V<=E;p.visible()!==O&&(p.visible(O),y=!0)}),b&&this.roomLayer.batchDraw(),y&&this.linkLayer.batchDraw()}clearCurrentRoomOverlay(){this.currentRoomOverlay.forEach(t=>t.destroy()),this.currentRoomOverlay=[],this.overlayLayer.batchDraw()}updateCurrentRoomOverlay(t){if(this.clearCurrentRoomOverlay(),t.area!==this.currentArea||t.z!==this.currentZIndex){this.overlayLayer.batchDraw();return}const e=new Map;e.set(t.id,t);const s=[],i=this.currentAreaInstance instanceof z?this.currentAreaInstance:void 0;this.currentAreaInstance&&this.currentZIndex!==void 0&&this.currentAreaInstance.getLinkExits(this.currentZIndex).filter(a=>a.a===t.id||a.b===t.id).forEach(a=>{const u=h.highlightCurrentRoom?this.exitRenderer.renderWithColor(a,I,this.currentZIndex):this.exitRenderer.render(a,this.currentZIndex);u&&s.push(u)});const r=h.highlightCurrentRoom?I:void 0;this.exitRenderer.renderSpecialExits(t,r).forEach(o=>{s.push(o)}),(h.highlightCurrentRoom?this.exitRenderer.renderStubs(t,I):this.exitRenderer.renderStubs(t)).forEach(o=>{s.push(o)}),[...Object.values(t.exits),...Object.values(t.specialExits)].forEach(o=>{const a=this.mapReader.getRoom(o),u=!i||i.hasVisitedRoom(o);a&&a.area===this.currentArea&&a.z===this.currentZIndex&&u&&e.set(o,a)}),s.forEach(o=>{this.overlayLayer.add(o),this.currentRoomOverlay.push(o)}),e.forEach((o,a)=>{const u=a===t.id,g=this.createOverlayRoomGroup(o,{stroke:u&&h.highlightCurrentRoom?I:h.lineColor});this.overlayLayer.add(g),this.currentRoomOverlay.push(g),this.exitRenderer.renderInnerExits(o).forEach(c=>{this.overlayLayer.add(c),this.currentRoomOverlay.push(c)})}),this.overlayLayer.batchDraw()}createOverlayRoomGroup(t,e){const s=new f.Group({x:t.x-h.roomSize/2,y:t.y-h.roomSize/2,listening:!1}),i=new f.Rect({x:0,y:0,width:h.roomSize,height:h.roomSize,fill:this.mapReader.getColorValue(t.env),stroke:e.stroke,strokeWidth:.025,strokeEnabled:!0});return s.add(i),this.renderSymbol(t,s),s}renderSymbol(t,e){if(t.roomChar!==void 0){const s=new f.Text({x:0,y:0,text:t.roomChar,fontSize:.45,fontStyle:"bold",fill:this.mapReader.getSymbolColor(t.env),align:"center",verticalAlign:"middle",width:h.roomSize,height:h.roomSize});e.add(s)}}renderExits(t){t.forEach(e=>{const s=this.exitRenderer.render(e,this.currentZIndex);s&&(this.linkLayer.add(s),this.standaloneExitNodes.push(s))})}renderLabels(t){t.forEach(e=>{if(h.labelRenderMode==="image"){if(!e.pixMap)return;const s=new Image;s.src=`data:image/png;base64,${e.pixMap}`;const i=new f.Image({x:e.X,y:-e.Y,width:e.Width,height:e.Height,image:s,listening:!1});this.linkLayer.add(i);return}this.renderLabelAsData(e)})}renderLabelAsData(t){var o;const e=new f.Group({listening:!1}),s=new f.Rect({x:t.X,y:-t.Y,width:t.Width,height:t.Height,listening:!1});(((o=t.BgColor)==null?void 0:o.alpha)??0)>0&&!h.transparentLabels?s.fill(this.getLabelColor(t.BgColor)):s.fillEnabled(!1),e.add(s);const i=Math.min(.75,t.Width/Math.max(t.Text.length/2,1)),r=Math.max(.1,Math.min(i,Math.max(t.Height*.9,.1))),n=new f.Text({x:t.X,y:-t.Y,width:t.Width,height:t.Height,text:t.Text,fontSize:r,fillEnabled:!0,fill:this.getLabelColor(t.FgColor),align:"center",verticalAlign:"middle",listening:!1});e.add(n),this.linkLayer.add(e)}getLabelColor(t){const e=((t==null?void 0:t.alpha)??255)/255,s=i=>Math.min(255,Math.max(0,i??0));return`rgba(${s(t==null?void 0:t.r)}, ${s(t==null?void 0:t.g)}, ${s(t==null?void 0:t.b)}, ${e})`}}const Z={rgbValue:"rgb(114, 1, 0)",symbolColor:[225,225,225]};function $(d){const t=d[0]/255,e=d[1]/255,s=d[2]/255,i=Math.max(t,e,s),r=Math.min(t,e,s);return(i+r)/2}class nt{constructor(t,e){this.rooms={},this.areas={},this.areaSources={},this.explorationEnabled=!1,this.colors={},t.forEach(s=>{s.rooms.forEach(r=>{r.y=-r.y,this.rooms[r.id]=r});const i=parseInt(s.areaId);this.areas[i]=new A(s),this.areaSources[i]=s}),this.colors=e.reduce((s,i)=>({...s,[i.envId]:{rgb:i.colors,rgbValue:`rgb(${i.colors.join(",")}`,symbolColor:$(i.colors)>.41?[25,25,25]:[225,255,255],symbolColorValue:$(i.colors)>.41?"rgb(25,25,25)":"rgb(225,255,255)"}}),{})}getArea(t){return this.areas[t]}getExplorationArea(t){const e=this.areas[t];if(e instanceof z)return e}getAreas(){return Object.values(this.areas)}getRooms(){return Object.values(this.rooms)}getRoom(t){return this.rooms[t]}ensureVisitedRooms(){return this.visitedRooms||(this.visitedRooms=new Set),this.visitedRooms}applyExplorationDecoration(){this.visitedRooms&&Object.entries(this.areaSources).forEach(([t,e])=>{const s=parseInt(t,10);this.areas[s]=new z(e,this.visitedRooms)})}decorateWithExploration(t){return t!==void 0?this.setVisitedRooms(t):this.ensureVisitedRooms(),this.applyExplorationDecoration(),this.explorationEnabled=!0,this.visitedRooms}getVisitedRooms(){return this.visitedRooms}clearExplorationDecoration(){Object.entries(this.areaSources).forEach(([t,e])=>{const s=parseInt(t,10);this.areas[s]=new A(e)}),this.explorationEnabled=!1}isExplorationEnabled(){return this.explorationEnabled}setVisitedRooms(t){return this.visitedRooms=t instanceof Set?t:new Set(t),this.explorationEnabled&&this.applyExplorationDecoration(),this.visitedRooms}addVisitedRoom(t){if(this.explorationEnabled){const i=this.getRoom(t);if(i){const r=this.getExplorationArea(i.area);if(r)return r.addVisitedRoom(t)}}const e=this.ensureVisitedRooms(),s=e.has(t);return e.add(t),!s}addVisitedRooms(t){const e=this.ensureVisitedRooms();let s=0;for(const i of t){if(this.explorationEnabled){const n=this.getRoom(i);if(n){const o=this.getExplorationArea(n.area);if(o){o.addVisitedRoom(i)&&s++;continue}}}const r=e.has(i);e.add(i),r||s++}return s}hasVisitedRoom(t){var e;return((e=this.visitedRooms)==null?void 0:e.has(t))??!1}getColorValue(t){var e;return((e=this.colors[t])==null?void 0:e.rgbValue)??Z.rgbValue}getSymbolColor(t,e){var n;const s=((n=this.colors[t])==null?void 0:n.symbolColor)??Z.symbolColor,i=Math.min(Math.max(e??1,0),1),r=s.join(",");return i!=1?`rgba(${r}, ${i})`:`rgba(${r})`}}function at(d){return d&&d.__esModule&&Object.prototype.hasOwnProperty.call(d,"default")?d.default:d}class ht{constructor(){this.keys=new Set,this.queue=[]}sort(){this.queue.sort((t,e)=>t.priority-e.priority)}set(t,e){const s=Number(e);if(isNaN(s))throw new TypeError('"priority" must be a number');return this.keys.has(t)?this.queue.map(i=>(i.key===t&&Object.assign(i,{priority:s}),i)):(this.keys.add(t),this.queue.push({key:t,priority:s})),this.sort(),this.queue.length}next(){const t=this.queue.shift();return this.keys.delete(t.key),t}isEmpty(){return this.queue.length===0}has(t){return this.keys.has(t)}get(t){return this.queue.find(e=>e.key===t)}}var ct=ht;function H(d,t){const e=new Map;for(const[s,i]of d)s!==t&&i instanceof Map?e.set(s,H(i,t)):s!==t&&e.set(s,i);return e}var lt=H;function ut(d){const t=Number(d);return!(isNaN(t)||t<=0)}function q(d){const t=new Map;return Object.keys(d).forEach(s=>{const i=d[s];if(i!==null&&typeof i=="object"&&!Array.isArray(i))return t.set(s,q(i));if(!ut(i))throw new Error(`Could not add node at key "${s}", make sure it's a valid node`,i);return t.set(s,Number(i))}),t}var dt=q;function K(d){if(!(d instanceof Map))throw new Error(`Invalid graph: Expected Map instead found ${typeof d}`);d.forEach((t,e)=>{if(typeof t=="object"&&t instanceof Map){K(t);return}if(typeof t!="number"||t<=0)throw new Error(`Values must be numbers greater than 0. Found value ${t} at ${e}`)})}var gt=K;const mt=ct,ft=lt,j=dt,_=gt;class pt{constructor(t){t instanceof Map?(_(t),this.graph=t):t?this.graph=j(t):this.graph=new Map}addNode(t,e){let s;return e instanceof Map?(_(e),s=e):s=j(e),this.graph.set(t,s),this}addVertex(t,e){return this.addNode(t,e)}removeNode(t){return this.graph=ft(this.graph,t),this}path(t,e,s={}){if(!this.graph.size)return s.cost?{path:null,cost:0}:null;const i=new Set,r=new mt,n=new Map;let o=[],a=0,u=[];if(s.avoid&&(u=[].concat(s.avoid)),u.includes(t))throw new Error(`Starting node (${t}) cannot be avoided`);if(u.includes(e))throw new Error(`Ending node (${e}) cannot be avoided`);for(r.set(t,0);!r.isEmpty();){const g=r.next();if(g.key===e){a=g.priority;let l=g.key;for(;n.has(l);)o.push(l),l=n.get(l);break}i.add(g.key),(this.graph.get(g.key)||new Map).forEach((l,m)=>{if(i.has(m)||u.includes(m))return null;if(!r.has(m))return n.set(m,g.key),r.set(m,g.priority+l);const R=r.get(m).priority,v=g.priority+l;return v<R?(n.set(m,g.key),r.set(m,v)):null})}return o.length?(s.trim?o.shift():o=o.concat([t]),s.reverse||(o=o.reverse()),s.cost?{path:o,cost:a}:o):s.cost?{path:null,cost:0}:null}shortestPath(...t){return this.path(...t)}}var yt=pt;const xt=at(yt),Rt={1:"north",2:"northeast",3:"northwest",4:"east",5:"west",6:"south",7:"southeast",8:"southwest",9:"up",10:"down",11:"in",12:"out"};class bt{constructor(t){this.cache=new Map,this.mapReader=t,this.graph=this.buildGraph()}buildGraph(){const t={};return this.mapReader.getRooms().forEach(e=>{const s={},i=new Set((e.exitLocks??[]).map(n=>Rt[n]).filter(n=>!!n)),r=new Set(e.mSpecialExitLocks??[]);Object.entries(e.exits??{}).forEach(([n,o])=>{i.has(n)||this.mapReader.getRoom(o)&&(s[o.toString()]=1)}),Object.values(e.specialExits??{}).forEach(n=>{r.has(n)||this.mapReader.getRoom(n)&&(s[n.toString()]=1)}),t[e.id.toString()]=s}),new xt(t)}findPath(t,e){const s=`${t}->${e}`;if(this.cache.has(s))return this.cache.get(s);if(t===e){const o=this.mapReader.getRoom(t)?[t]:null;return this.cache.set(s,o),o}if(!this.mapReader.getRoom(t)||!this.mapReader.getRoom(e))return this.cache.set(s,null),null;const i=this.graph.path(t.toString(),e.toString()),r=Array.isArray(i)?i:i==null?void 0:i.path,n=r?r.map(o=>Number(o)):null;return this.cache.set(s,n),n}}exports.ExplorationArea=z;exports.MapReader=nt;exports.PathFinder=bt;exports.Renderer=ot;exports.Settings=h;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("konva"),q=["north","south","east","west","northeast","northwest","southeast","southwest"],O={north:"n",south:"s",east:"e",west:"w",northeast:"ne",northwest:"nw",southeast:"se",southwest:"sw",up:"u",down:"d",in:"i",out:"o"},st={north:{x:0,y:-1},south:{x:0,y:1},east:{x:1,y:0},west:{x:-1,y:0},northeast:{x:1,y:-1},northwest:{x:-1,y:-1},southeast:{x:1,y:1},southwest:{x:-1,y:1}},K=["north","south","east","west","northeast","northwest","southeast","southwest"],lt={north:"south",south:"north",east:"west",west:"east",northeast:"southwest",northwest:"southeast",southeast:"northwest",southwest:"northeast"};function dt(g){return g?Object.prototype.hasOwnProperty.call(st,g):!1}function S(g,t,e,s=1){if(!dt(e))return{x:g,y:t};const i=st[e];return{x:g+i.x*s,y:t+i.y*s}}const A={OPEN_DOOR:"rgb(10, 155, 10)",CLOSED_DOOR:"rgb(226, 205, 59)",LOCKED_DOOR:"rgb(155, 10, 10)",ONE_WAY_FILL:"rgb(155, 10, 10)"},ut={1:"north",2:"northeast",3:"northwest",4:"east",5:"west",6:"south",7:"southeast",8:"southwest",9:"up",10:"down",11:"in",12:"out"},gt=["up","down","in","out"];function ft(g){switch(g){case 1:return A.OPEN_DOOR;case 2:return A.CLOSED_DOOR;default:return A.LOCKED_DOOR}}class mt{constructor(t,e){this.mapReader=t,this.mapRenderer=e}render(t,e){return this.renderWithColor(t,h.lineColor,e)}renderWithColor(t,e,s){return t.aDir&&t.bDir?this.renderTwoWayExit(t,e,s):this.renderOneWayExit(t,e)}renderTwoWayExit(t,e,s){const i=this.mapReader.getRoom(t.a),r=this.mapReader.getRoom(t.b);if(!i||!r||!t.aDir||!t.bDir||!q.includes(t.aDir)||!q.includes(t.bDir)||i.customLines[O[t.aDir]]&&r.customLines[O[t.bDir]]||i.z!==r.z&&(s!==r.z&&i.customLines[O[t.aDir]]||s!==i.z&&r.customLines[O[t.bDir]]))return;const n=new f.Group,o=[];if(o.push(...Object.values(S(i.x,i.y,t.aDir,h.roomSize/2))),o.push(...Object.values(S(r.x,r.y,t.bDir,h.roomSize/2))),i.doors[O[t.aDir]]||r.doors[O[t.bDir]]){const d=this.renderDoor(o,i.doors[O[t.aDir]]??r.doors[O[t.bDir]]);n.add(d)}const a=new f.Line({points:o,stroke:e,strokeWidth:.025});return n.add(a),n}renderOneWayExit(t,e){const s=t.aDir?this.mapReader.getRoom(t.a):this.mapReader.getRoom(t.b),i=t.aDir?this.mapReader.getRoom(t.b):this.mapReader.getRoom(t.a),r=t.aDir?t.aDir:t.bDir;if(!r||!s||!i||s.customLines[O[r]||r])return;if(s.area!=i.area&&r)return this.renderAreaExit(s,r,e);let n={x:i.x,y:i.y};(i.area!==s.area||i.z!==s.z)&&(n=S(s.x,s.y,r,h.roomSize/2));const o=S(s.x,s.y,r,.3),a=o.x-(o.x-n.x)/2,d=o.y-(o.y-n.y)/2,u=new f.Group,c=[];c.push(...Object.values(S(s.x,s.y,r,h.roomSize/2))),c.push(n.x,n.y);const y=new f.Line({points:c,stroke:e,strokeWidth:.025,dashEnabled:!0,dash:[.1,.05]});u.add(y);const l=new f.Arrow({points:[c[0],c[1],a,d],pointerLength:.5,pointerWidth:.35,strokeWidth:.035,stroke:e,fill:A.ONE_WAY_FILL,dashEnabled:!0,dash:[.1,.05]});return u.add(l),u}renderAreaExit(t,e,s){const i=S(t.x,t.y,e,h.roomSize/2),r=S(t.x,t.y,e,h.roomSize*1.5),n=s??this.mapReader.getColorValue(t.env);return new f.Arrow({points:[i.x,i.y,r.x,r.y],pointerLength:.3,pointerWidth:.3,strokeWidth:.035,stroke:n,fill:n})}renderSpecialExits(t,e){return Object.entries(t.customLines).map(([s,i])=>{const r=[t.x,t.y];i.points.reduce((u,c)=>(u.push(c.x,-c.y),u),r);const n=i.attributes.arrow?f.Arrow:f.Line,o=e??`rgb(${i.attributes.color.r}, ${i.attributes.color.g}, ${i.attributes.color.b})`,a=new n({points:r,strokeWidth:.025,stroke:o,fill:e??`rgb(${i.attributes.color.r}, ${i.attributes.color.g} , ${i.attributes.color.b})`,pointerLength:.3,pointerWidth:.2});let d=i.attributes.style;return d==="dot line"?(a.dash([.05,.05]),a.dashOffset(.1)):d==="dash line"?a.dash([.4,.2]):d==="solid line"||d!==void 0&&console.log("Brak opisu stylu: "+d),a})}renderStubs(t,e=h.lineColor){return t.stubs.map(s=>{const i=ut[s],r=S(t.x,t.y,i,h.roomSize/2),n=S(t.x,t.y,i,h.roomSize/2+.5),o=[r.x,r.y,n.x,n.y];return new f.Line({points:o,stroke:e,strokeWidth:.025})})}renderInnerExits(t){return gt.map(e=>{if(t.exits[e]){const s=new f.Group,i=new f.RegularPolygon({x:t.x,y:t.y,sides:3,fill:this.mapReader.getSymbolColor(t.env,.6),stroke:this.mapReader.getSymbolColor(t.env),strokeWidth:.025,radius:h.roomSize/5,scaleX:1.4,scaleY:.8});s.add(i);let r=t.doors[e];if(r!==void 0)switch(r){case 1:i.stroke(A.OPEN_DOOR);break;case 2:i.stroke(A.CLOSED_DOOR);break;default:i.stroke(A.LOCKED_DOOR)}switch(e){case"up":i.position(S(t.x,t.y,"south",h.roomSize/4));break;case"down":i.rotation(180),i.position(S(t.x,t.y,"north",h.roomSize/4));break;case"in":const n=i.clone();n.rotation(-90),n.position(S(t.x,t.y,"east",h.roomSize/4)),s.add(n),i.rotation(90),i.position(S(t.x,t.y,"west",h.roomSize/4));break;case"out":const o=i.clone();o.rotation(90),o.position(S(t.x,t.y,"east",h.roomSize/4)),s.add(o),i.rotation(-90),i.position(S(t.x,t.y,"west",h.roomSize/4));break}return s}}).filter(e=>e!==void 0)}renderDoor(t,e){const s={x:t[0]+(t[2]-t[0])/2,y:t[1]+(t[3]-t[1])/2};return new f.Rect({x:s.x-h.roomSize/4,y:s.y-h.roomSize/4,width:h.roomSize/2,height:h.roomSize/2,stroke:ft(e),strokeWidth:.025})}}class it{constructor(t,e){this.rooms=[],this.labels=[],this.rooms=t,this.bounds=this.createBounds(),this.labels=e}getRooms(){return this.rooms}getLabels(){return this.labels}getBounds(){return this.bounds}createBounds(){return this.rooms.reduce((t,e)=>({minX:Math.min(t.minX,e.x),maxX:Math.max(t.maxX,e.x),minY:Math.min(t.minY,e.y),maxY:Math.max(t.maxY,e.y)}),{minX:Number.POSITIVE_INFINITY,maxX:Number.NEGATIVE_INFINITY,minY:Number.POSITIVE_INFINITY,maxY:Number.NEGATIVE_INFINITY})}}class ${constructor(t){this.planes={},this.exits=new Map,this.version=0,this.area=t,this.planes=this.createPlanes(),this.createExits()}getAreaName(){return this.area.areaName}getAreaId(){return parseInt(this.area.areaId)}getVersion(){return this.version}markDirty(){this.version++}getPlane(t){return this.planes[t]}getPlanes(){return Object.values(this.planes)}getRooms(){return this.area.rooms}getLinkExits(t){return Array.from(this.exits.values()).filter(e=>e.zIndex.includes(t))}createPlanes(){const t=this.area.rooms.reduce((e,s)=>(e[s.z]||(e[s.z]=[]),e[s.z].push(s),e),{});return Object.entries(t).reduce((e,[s,i])=>(e[+s]=new it(i,this.area.labels.filter(r=>r.Z===+s)),e),{})}createExits(){this.area.rooms.forEach(t=>{Object.entries(t.specialExits).forEach(([e,s])=>this.createHalfExit(t.id,s,t.z,e)),Object.entries(t.exits).forEach(([e,s])=>this.createHalfExit(t.id,s,t.z,e))})}createHalfExit(t,e,s,i){if(t===e)return;const r=Math.min(t,e),n=Math.max(t,e),o=`${r}-${n}`;let a=this.exits.get(o);a||(a={a:r,b:n,zIndex:[s]}),r==t?a.aDir=i:a.bDir=i,a.zIndex.push(s),this.exits.set(o,a)}}class Q extends it{constructor(t,e){super(t.getRooms(),t.getLabels()),this.basePlane=t,this.visitedRooms=e}getRooms(){return this.basePlane.getRooms().filter(t=>this.visitedRooms.has(t.id))}getLabels(){return this.basePlane.getLabels()}getBounds(){const t=this.getRooms();return t.length?t.reduce((e,s)=>({minX:Math.min(e.minX,s.x),maxX:Math.max(e.maxX,s.x),minY:Math.min(e.minY,s.y),maxY:Math.max(e.maxY,s.y)}),{minX:Number.POSITIVE_INFINITY,maxX:Number.NEGATIVE_INFINITY,minY:Number.POSITIVE_INFINITY,maxY:Number.NEGATIVE_INFINITY}):this.basePlane.getBounds()}}class Z extends ${constructor(t,e){super(t),this.planeCache=new WeakMap,this.visitedRooms=e instanceof Set?e:new Set(e??[]),this.areaRoomIds=new Set(t.rooms.map(s=>s.id))}getPlane(t){const e=super.getPlane(t);if(!e)return e;let s=this.planeCache.get(e);return s||(s=new Q(e,this.visitedRooms),this.planeCache.set(e,s)),s}getPlanes(){return super.getPlanes().map(t=>{let e=this.planeCache.get(t);return e||(e=new Q(t,this.visitedRooms),this.planeCache.set(t,e)),e})}getLinkExits(t){return super.getLinkExits(t).filter(e=>this.visitedRooms.has(e.a)||this.visitedRooms.has(e.b))}getVisitedRoomCount(){return super.getRooms().reduce((t,e)=>t+(this.visitedRooms.has(e.id)?1:0),0)}getTotalRoomCount(){return this.areaRoomIds.size}hasVisitedRoom(t){return this.areaRoomIds.has(t)&&this.visitedRooms.has(t)}getVisitedRoomIds(){return super.getRooms().filter(t=>this.visitedRooms.has(t.id)).map(t=>t.id)}addVisitedRoom(t){const e=this.visitedRooms.has(t);this.visitedRooms.add(t);const s=!e&&this.areaRoomIds.has(t);return s&&this.markDirty(),s}addVisitedRooms(t){let e=0;for(const s of t){const i=this.visitedRooms.has(s);this.visitedRooms.add(s),!i&&this.areaRoomIds.has(s)&&e++}return e>0&&this.markDirty(),e}}class pt{constructor(t,e){this.paths=[],this.mapReader=t,this.overlayLayer=e}renderPath(t,e,s,i="#66E64D"){if(e===void 0||s===void 0)return;const r=t.map(c=>this.mapReader.getRoom(c)).filter(c=>c!==void 0),n=[];let o=null;const a=()=>{o&&(o.length<4&&n.pop(),o=null)},d=()=>(o||(o=[],n.push(o)),o);r.forEach((c,y)=>{if(!this.isRoomVisible(c,e,s))return;const l=y>0?r[y-1]:void 0,m=y<r.length-1?r[y+1]:void 0;if(this.isRoomVisible(l,e,s))d();else{a();const R=d();if(l){const b=this.getDirectionTowards(c,l);if(b){const D=S(c.x,c.y,b,h.roomSize);R.push(D.x,D.y)}}}if(o==null||o.push(c.x,c.y),!this.isRoomVisible(m,e,s)&&m){const R=this.getDirectionTowards(c,m);if(R){const b=S(c.x,c.y,R,h.roomSize);o==null||o.push(b.x,b.y)}a()}}),a();const u=n.filter(c=>c.length>=4).map(c=>new f.Line({points:c,stroke:i,strokeWidth:.1}));return u.forEach(c=>{this.overlayLayer.add(c),this.paths.push(c)}),u[0]}clearPaths(){this.paths.forEach(t=>{t.destroy()}),this.paths=[]}isRoomVisible(t,e,s){return t?t.area===e&&t.z===s:!1}getDirectionTowards(t,e){for(const s of K)if(t.exits[s]===e.id)return s;for(const s of K)if(e.exits[s]===t.id)return lt[s]}}const rt=.6,X=75,bt="rgb(225, 255, 225)",W="rgb(120, 72, 0)",k=class k{};k.roomSize=rt,k.lineColor=bt,k.instantMapMove=!1,k.highlightCurrentRoom=!0,k.cullingEnabled=!0,k.cullingMode="indexed",k.cullingBounds=null,k.labelRenderMode="image",k.cullingDebug=!1;let h=k;class xt{constructor(t,e){this.highlights=new Map,this.currentZoom=1,this.currentRoomOverlay=[],this.roomNodes=new Map,this.standaloneExitNodes=[],this.spatialBucketSize=5,this.roomSpatialIndex=new Map,this.exitSpatialIndex=new Map,this.visibleRooms=new Set,this.visibleStandaloneExitNodes=new Set,this.cullingScheduled=!1,this.cullingBucketDebug=[],this.stage=new f.Stage({container:t,width:t.clientWidth,height:t.clientHeight,draggable:!0}),window.addEventListener("resize",()=>{this.onResize(t)}),t.addEventListener("resize",()=>{this.onResize(t)}),this.linkLayer=new f.Layer({listening:!1}),this.stage.add(this.linkLayer),this.roomLayer=new f.Layer,this.stage.add(this.roomLayer),this.overlayLayer=new f.Layer({listening:!1}),this.stage.add(this.overlayLayer),this.debugLayer=new f.Layer({listening:!1}),this.stage.add(this.debugLayer),this.positionLayer=new f.Layer({listening:!1}),this.stage.add(this.positionLayer),this.mapReader=e,this.exitRenderer=new mt(e,this),this.pathRenderer=new pt(e,this.overlayLayer),this.initScaling(1.1),this.stage.on("dragmove",()=>this.scheduleRoomCulling()),this.stage.on("dragend",()=>this.scheduleRoomCulling())}onResize(t){this.stage.width(t.clientWidth),this.stage.height(t.clientHeight),this.currentRoomId&&this.centerOnRoom(this.mapReader.getRoom(this.currentRoomId),!1),this.stage.batchDraw(),this.scheduleRoomCulling()}initScaling(t){f.hitOnDragEnabled=!0;let e,s=!1,i=!1;this.stage.on("touchstart",r=>{const n=r.evt.touches;n&&n.length>1?(i=!0,this.stage.isDragging()&&(this.stage.stopDrag(),s=!0),this.stage.draggable(!1)):(i=!1,this.stage.draggable(!0))}),this.stage.on("touchend touchcancel",r=>{e=void 0;const n=r.evt.touches;(!n||n.length<=1)&&(i=!1,this.stage.draggable(!0))}),this.stage.on("wheel",r=>{r.evt.preventDefault();const n=this.stage.scaleX(),o=this.stage.getPointerPosition();if(!o)return;const a={x:(o.x-this.stage.x())/n,y:(o.y-this.stage.y())/n};let d=r.evt.deltaY>0?-1:1;r.evt.ctrlKey&&(d=-d);const u=d>0?this.currentZoom*t:this.currentZoom/t,c=u*X,y=this.setZoom(u),l={x:o.x-a.x*c,y:o.y-a.y*c};this.stage.position(l),this.scheduleRoomCulling(),y&&this.emitZoomChangeEvent()}),this.stage.on("touchmove",r=>{const n=r.evt.touches,o=n==null?void 0:n[0],a=n==null?void 0:n[1];if(a||i&&(i=!1,this.stage.draggable(!0)),o&&!a&&s&&!this.stage.isDragging()&&(this.stage.startDrag(),s=!1),!o||!a){e=void 0;return}r.evt.preventDefault(),this.stage.isDragging()&&(this.stage.stopDrag(),s=!0),i||(i=!0,this.stage.draggable(!1));const d=this.stage.container().getBoundingClientRect(),u={x:o.clientX-d.left,y:o.clientY-d.top},c={x:a.clientX-d.left,y:a.clientY-d.top},y=Math.hypot(u.x-c.x,u.y-c.y);if(e===void 0){e=y;return}if(e===0)return;const l=this.stage.scaleX(),m=this.stage.x(),w=this.stage.y(),x={x:this.stage.width()/2,y:this.stage.height()/2},R={x:(x.x-m)/l,y:(x.y-w)/l},b=this.currentZoom*(y/e),D=this.setZoom(b),C=this.stage.scaleX(),z={x:x.x-R.x*C,y:x.y-R.y*C};this.stage.position(z),this.stage.batchDraw(),this.scheduleRoomCulling(),e=y,D&&this.emitZoomChangeEvent()})}drawArea(t,e){const s=this.mapReader.getArea(t);if(!s)return;const i=s.getPlane(e);i&&(this.currentArea=t,this.currentAreaInstance=s,this.currentZIndex=e,this.currentAreaVersion=s.getVersion(),this.clearCurrentRoomOverlay(),this.roomLayer.destroyChildren(),this.linkLayer.destroyChildren(),this.debugLayer.destroyChildren(),this.roomNodes.clear(),this.standaloneExitNodes=[],this.roomSpatialIndex.clear(),this.exitSpatialIndex.clear(),this.visibleRooms.clear(),this.visibleStandaloneExitNodes.clear(),this.cullingViewportDebug=void 0,this.cullingSearchDebug=void 0,this.cullingBucketDebug=[],this.spatialBucketSize=this.computeSpatialBucketSize(),this.stage.scale({x:X*this.currentZoom,y:X*this.currentZoom}),this.renderLabels(i.getLabels()),this.renderExits(s.getLinkExits(e)),this.renderRooms(i.getRooms()??[]),this.refreshHighlights(),this.stage.batchDraw(),this.scheduleRoomCulling())}computeSpatialBucketSize(){return Math.max(h.roomSize*10,5)}getBucketKey(t,e){return`${t},${e}`}forEachBucket(t,e,s,i,r){const n=this.spatialBucketSize,o=Math.min(t,s),a=Math.max(t,s),d=Math.min(e,i),u=Math.max(e,i),c=Math.floor(o/n),y=Math.floor(a/n),l=Math.floor(d/n),m=Math.floor(u/n);for(let w=c;w<=y;w++)for(let x=l;x<=m;x++)r(this.getBucketKey(w,x))}addRoomToSpatialIndex(t){const e=h.roomSize/2,s=t.room.x-e,i=t.room.x+e,r=t.room.y-e,n=t.room.y+e;this.forEachBucket(s,r,i,n,o=>{let a=this.roomSpatialIndex.get(o);a||(a=new Set,this.roomSpatialIndex.set(o,a)),a.add(t)})}addStandaloneExitToSpatialIndex(t){const e=t.getClientRect({relativeTo:this.linkLayer}),s=e.x,i=e.x+e.width,r=e.y,n=e.y+e.height;this.forEachBucket(s,r,i,n,o=>{let a=this.exitSpatialIndex.get(o);a||(a=new Set,this.exitSpatialIndex.set(o,a)),a.add(t)})}collectRoomCandidates(t,e,s,i,r){const n=new Set;return this.forEachBucket(t,e,s,i,o=>{r&&r.add(o);const a=this.roomSpatialIndex.get(o);a==null||a.forEach(d=>n.add(d))}),n}collectStandaloneExitCandidates(t,e,s,i,r){const n=new Set;return this.forEachBucket(t,e,s,i,o=>{r&&r.add(o);const a=this.exitSpatialIndex.get(o);a==null||a.forEach(d=>n.add(d))}),n}getBucketBounds(t){const[e,s]=t.split(","),i=Number.parseInt(e,10),r=Number.parseInt(s,10),n=this.spatialBucketSize;return{x:i*n,y:r*n,width:n,height:n}}emitRoomContextEvent(t,e,s){const i=this.stage.container(),r=i.getBoundingClientRect(),n={roomId:t,position:{x:e-r.left,y:s-r.top}},o=new CustomEvent("roomcontextmenu",{detail:n});i.dispatchEvent(o)}emitZoomChangeEvent(){const t=new CustomEvent("zoom",{detail:{zoom:this.currentZoom}});this.stage.container().dispatchEvent(t)}setZoom(t){return this.currentZoom===t?!1:(this.currentZoom=t,this.stage.scale({x:X*t,y:X*t}),this.scheduleRoomCulling(),!0)}getZoom(){return this.currentZoom}setCullingMode(t){h.cullingMode=t,h.cullingEnabled=t!=="none",this.scheduleRoomCulling()}getCullingMode(){return h.cullingMode}setCullingDebug(t){h.cullingDebug=t,this.scheduleRoomCulling()}getCurrentArea(){return this.currentArea?this.mapReader.getArea(this.currentArea):void 0}setPosition(t){const e=this.mapReader.getRoom(t);if(!e)return;const s=this.mapReader.getArea(e.area),i=s==null?void 0:s.getVersion();let r=this.currentArea!==e.area||this.currentZIndex!==e.z;(this.currentArea!==e.area||this.currentZIndex!==e.z||i!==void 0&&this.currentAreaVersion!==i||s!==void 0&&this.currentAreaInstance!==s)&&this.drawArea(e.area,e.z),this.positionRender||(this.positionRender=new f.Circle({x:e.x,y:e.y,radius:rt*.85,stroke:"rgb(0, 229, 178)",strokeWidth:.1,dash:[.05,.05],dashEnabled:!0}),this.positionLayer.add(this.positionRender)),this.centerOnRoom(e,r),this.updateCurrentRoomOverlay(e)}renderPath(t,e){return this.pathRenderer.renderPath(t,this.currentArea,this.currentZIndex,e)}clearPaths(){this.pathRenderer.clearPaths()}renderHighlight(t,e){const s=this.mapReader.getRoom(t);if(!s)return;const i=this.highlights.get(t);i!=null&&i.shape&&(i.shape.destroy(),delete i.shape);const r={color:e,area:s.area,z:s.z};if(this.highlights.set(t,r),s.area===this.currentArea&&s.z===this.currentZIndex){const n=this.createHighlightShape(s,e);return this.overlayLayer.add(n),r.shape=n,this.overlayLayer.batchDraw(),n}return r.shape}clearHighlights(){this.highlights.forEach(({shape:t})=>t==null?void 0:t.destroy()),this.highlights.clear(),this.overlayLayer.batchDraw()}refreshHighlights(){this.highlights.forEach((t,e)=>{var r;if((r=t.shape)==null||r.destroy(),delete t.shape,t.area!==this.currentArea||t.z!==this.currentZIndex)return;const s=this.mapReader.getRoom(e);if(!s)return;const i=this.createHighlightShape(s,t.color);this.overlayLayer.add(i),t.shape=i}),this.overlayLayer.batchDraw()}createHighlightShape(t,e){return new f.Circle({x:t.x,y:t.y,radius:h.roomSize*.9,stroke:e,strokeWidth:.15,dash:[.1,.05],dashEnabled:!0,listening:!1})}centerOnRoom(t,e=!1){var d;this.currentRoomId=t.id;const s={x:t.x,y:t.y};(d=this.positionRender)==null||d.position(t);const r=this.stage.getAbsoluteTransform().point(s),n={x:this.stage.width()/2,y:this.stage.height()/2},o=n.x-r.x,a=n.y-r.y;this.currentTransition&&(this.currentTransition.pause(),this.currentTransition.destroy(),delete this.currentTransition),e||h.instantMapMove?(this.stage.position({x:this.stage.x()+o,y:this.stage.y()+a}),this.scheduleRoomCulling()):(this.currentTransition=new f.Tween({node:this.stage,x:this.stage.x()+o,y:this.stage.y()+a,duration:.2,easing:f.Easings.EaseInOut,onUpdate:()=>this.scheduleRoomCulling(),onFinish:()=>this.scheduleRoomCulling()}),this.currentTransition.play())}renderRooms(t){t.forEach(e=>{const s=new f.Group({x:e.x-h.roomSize/2,y:e.y-h.roomSize/2}),i=new f.Rect({x:0,y:0,width:h.roomSize,height:h.roomSize,fill:this.mapReader.getColorValue(e.env),strokeWidth:.025,stroke:h.lineColor}),r=(l,m)=>this.emitRoomContextEvent(e.id,l,m);s.on("mouseenter",()=>{this.stage.container().style.cursor="pointer"}),s.on("mouseleave",()=>{this.stage.container().style.cursor="auto"}),s.on("contextmenu",l=>{l.evt.preventDefault();const m=l.evt;r(m.clientX,m.clientY)});let n,o,a;const d=()=>{a!==void 0&&(this.stage.draggable(a),a=void 0)},u=()=>{n!==void 0&&(window.clearTimeout(n),n=void 0),o=void 0,d()};s.on("touchstart",l=>{var w;if(u(),l.evt.touches&&l.evt.touches.length>1)return;const m=(w=l.evt.touches)==null?void 0:w[0];m&&(o={clientX:m.clientX,clientY:m.clientY},a=this.stage.draggable(),this.stage.draggable(!1),n=window.setTimeout(()=>{o&&r(o.clientX,o.clientY),u()},500))}),s.on("touchend",u),s.on("touchmove",l=>{var D;if(!o)return;const m=(D=l.evt.touches)==null?void 0:D[0];if(!m){u();return}const w=m.clientX-o.clientX,x=m.clientY-o.clientY,R=w*w+x*x,b=10;if(R>b*b){const C=a;u(),C&&this.stage.startDrag()}}),s.on("touchcancel",u),s.add(i),this.renderSymbol(e,s),this.roomLayer.add(s);const c=[];this.exitRenderer.renderSpecialExits(e).forEach(l=>{this.linkLayer.add(l),c.push(l)}),this.exitRenderer.renderStubs(e).forEach(l=>{this.linkLayer.add(l),c.push(l)}),this.exitRenderer.renderInnerExits(e).forEach(l=>{this.roomLayer.add(l)});const y={room:e,group:s,linkNodes:c};this.roomNodes.set(e.id,y),this.addRoomToSpatialIndex(y)})}scheduleRoomCulling(){this.cullingScheduled||(this.cullingScheduled=!0,window.requestAnimationFrame(()=>{this.cullingScheduled=!1,this.updateRoomCulling()}))}updateRoomCulling(){if(this.roomNodes.size===0&&this.standaloneExitNodes.length===0)return;const t=this.stage.scaleX();if(!t)return;const e=this.stage.position(),s=h.roomSize/2,i=h.cullingBounds,r=i?i.x:0,n=i?i.x+i.width:this.stage.width(),o=i?i.y:0,a=i?i.y+i.height:this.stage.height(),d=Math.min(r,n),u=Math.max(r,n),c=Math.min(o,a),y=Math.max(o,a),l=(d-e.x)/t,m=(u-e.x)/t,w=(c-e.y)/t,x=(y-e.y)/t;let R=!1,b=!1;const D=h.cullingEnabled?h.cullingMode??"indexed":"none",C=l-s,z=m+s,N=w-s,V=x+s;if(D==="none"){this.roomNodes.forEach(p=>{p.group.visible()||(p.group.visible(!0),R=!0),p.linkNodes.forEach(v=>{v.visible()||(v.visible(!0),b=!0)})}),this.standaloneExitNodes.forEach(p=>{p.visible()||(p.visible(!0),b=!0)}),R&&this.roomLayer.batchDraw(),b&&this.linkLayer.batchDraw(),this.visibleRooms=new Set(this.roomNodes.values()),this.visibleStandaloneExitNodes=new Set(this.standaloneExitNodes),this.updateCullingDebugVisuals({mode:D,minX:l,minY:w,maxX:m,maxY:x,searchMinX:C,searchMinY:N,searchMaxX:z,searchMaxY:V});return}if(D==="basic"){const p=new Set;this.roomNodes.forEach(E=>{const L=E.room.x-s,P=E.room.x+s,M=E.room.y-s,I=E.room.y+s,T=P>=l&&L<=m&&I>=w&&M<=x;E.group.visible()!==T&&(E.group.visible(T),R=!0),E.linkNodes.forEach(Y=>{Y.visible()!==T&&(Y.visible(T),b=!0)}),T&&p.add(E)});const v=new Set;this.standaloneExitNodes.forEach(E=>{const L=E.getClientRect({relativeTo:this.linkLayer}),P=L.x,M=L.x+L.width,I=L.y,T=L.y+L.height,Y=M>=l&&P<=m&&T>=w&&I<=x;E.visible()!==Y&&(E.visible(Y),b=!0),Y&&v.add(E)}),this.visibleRooms=p,this.visibleStandaloneExitNodes=v,R&&this.roomLayer.batchDraw(),b&&this.linkLayer.batchDraw(),this.updateCullingDebugVisuals({mode:D,minX:l,minY:w,maxX:m,maxY:x,searchMinX:C,searchMinY:N,searchMaxX:z,searchMaxY:V});return}const j=h.cullingDebug?new Set:void 0,B=h.cullingDebug?new Set:void 0,ht=this.collectRoomCandidates(C,N,z,V,j),F=new Set,_=new Set;ht.forEach(p=>{F.add(p);const v=p.room.x-s,E=p.room.x+s,L=p.room.y-s,P=p.room.y+s,M=E>=l&&v<=m&&P>=w&&L<=x;p.group.visible()!==M&&(p.group.visible(M),R=!0),p.linkNodes.forEach(I=>{I.visible()!==M&&(I.visible(M),b=!0)}),M&&_.add(p)}),this.visibleRooms.forEach(p=>{F.has(p)||(p.group.visible()&&(p.group.visible(!1),R=!0),p.linkNodes.forEach(v=>{v.visible()&&(v.visible(!1),b=!0)}))}),this.visibleRooms=_;const ct=this.collectStandaloneExitCandidates(C,N,z,V,B),G=new Set,H=new Set;ct.forEach(p=>{G.add(p);const v=p.getClientRect({relativeTo:this.linkLayer}),E=v.x,L=v.x+v.width,P=v.y,M=v.y+v.height,I=L>=l&&E<=m&&M>=w&&P<=x;p.visible()!==I&&(p.visible(I),b=!0),I&&H.add(p)}),this.visibleStandaloneExitNodes.forEach(p=>{!G.has(p)&&p.visible()&&(p.visible(!1),b=!0)}),this.visibleStandaloneExitNodes=H,R&&this.roomLayer.batchDraw(),b&&this.linkLayer.batchDraw(),this.updateCullingDebugVisuals({mode:D,minX:l,minY:w,maxX:m,maxY:x,searchMinX:C,searchMinY:N,searchMaxX:z,searchMaxY:V,roomBuckets:j,exitBuckets:B})}updateCullingDebugVisuals({mode:t,minX:e,minY:s,maxX:i,maxY:r,searchMinX:n,searchMinY:o,searchMaxX:a,searchMaxY:d,roomBuckets:u,exitBuckets:c}){if(!h.cullingDebug){this.debugLayer.children.length>0&&(this.debugLayer.destroyChildren(),this.debugLayer.batchDraw()),this.cullingViewportDebug=void 0,this.cullingSearchDebug=void 0,this.cullingBucketDebug=[];return}this.debugLayer.destroyChildren();const y=Math.max(0,i-e),l=Math.max(0,r-s),m=new f.Rect({x:e,y:s,width:y,height:l,stroke:"rgba(102, 255, 204, 0.9)",strokeWidth:.1,dash:[.4,.2],listening:!1});if(this.debugLayer.add(m),this.cullingViewportDebug=m,n<e||o<s||a>i||d>r){const x=new f.Rect({x:n,y:o,width:Math.max(0,a-n),height:Math.max(0,d-o),stroke:"rgba(80, 160, 255, 0.75)",strokeWidth:.08,dash:[.3,.15],fill:"rgba(80, 160, 255, 0.15)",listening:!1});this.debugLayer.add(x),this.cullingSearchDebug=x}else this.cullingSearchDebug=void 0;if(this.cullingBucketDebug=[],t==="indexed"&&(u!=null&&u.size||c!=null&&c.size)){const x=new Map;u==null||u.forEach(R=>{const b=x.get(R);x.set(R,{rooms:!0,exits:(b==null?void 0:b.exits)??!1})}),c==null||c.forEach(R=>{const b=x.get(R);x.set(R,{rooms:(b==null?void 0:b.rooms)??!1,exits:!0})}),x.forEach(({rooms:R,exits:b},D)=>{const C=this.getBucketBounds(D),z=R&&b?"rgba(255, 196, 102, 0.18)":R?"rgba(102, 255, 204, 0.18)":"rgba(255, 196, 102, 0.12)",N=R&&b?"rgba(255, 196, 102, 0.75)":R?"rgba(102, 255, 204, 0.8)":"rgba(255, 196, 102, 0.6)",V=new f.Rect({...C,stroke:N,strokeWidth:.05,fill:z,listening:!1});this.debugLayer.add(V),this.cullingBucketDebug.push(V)})}this.debugLayer.batchDraw()}clearCurrentRoomOverlay(){this.currentRoomOverlay.forEach(t=>t.destroy()),this.currentRoomOverlay=[],this.overlayLayer.batchDraw()}updateCurrentRoomOverlay(t){if(this.clearCurrentRoomOverlay(),t.area!==this.currentArea||t.z!==this.currentZIndex){this.overlayLayer.batchDraw();return}const e=new Map;e.set(t.id,t);const s=[],i=this.currentAreaInstance instanceof Z?this.currentAreaInstance:void 0;this.currentAreaInstance&&this.currentZIndex!==void 0&&this.currentAreaInstance.getLinkExits(this.currentZIndex).filter(a=>a.a===t.id||a.b===t.id).forEach(a=>{const d=h.highlightCurrentRoom?this.exitRenderer.renderWithColor(a,W,this.currentZIndex):this.exitRenderer.render(a,this.currentZIndex);d&&s.push(d)});const r=h.highlightCurrentRoom?W:void 0;this.exitRenderer.renderSpecialExits(t,r).forEach(o=>{s.push(o)}),(h.highlightCurrentRoom?this.exitRenderer.renderStubs(t,W):this.exitRenderer.renderStubs(t)).forEach(o=>{s.push(o)}),[...Object.values(t.exits),...Object.values(t.specialExits)].forEach(o=>{const a=this.mapReader.getRoom(o),d=!i||i.hasVisitedRoom(o);a&&a.area===this.currentArea&&a.z===this.currentZIndex&&d&&e.set(o,a)}),s.forEach(o=>{this.overlayLayer.add(o),this.currentRoomOverlay.push(o)}),e.forEach((o,a)=>{const d=a===t.id,u=this.createOverlayRoomGroup(o,{stroke:d&&h.highlightCurrentRoom?W:h.lineColor});this.overlayLayer.add(u),this.currentRoomOverlay.push(u),this.exitRenderer.renderInnerExits(o).forEach(c=>{this.overlayLayer.add(c),this.currentRoomOverlay.push(c)})}),this.overlayLayer.batchDraw()}createOverlayRoomGroup(t,e){const s=new f.Group({x:t.x-h.roomSize/2,y:t.y-h.roomSize/2,listening:!1}),i=new f.Rect({x:0,y:0,width:h.roomSize,height:h.roomSize,fill:this.mapReader.getColorValue(t.env),stroke:e.stroke,strokeWidth:.025,strokeEnabled:!0});return s.add(i),this.renderSymbol(t,s),s}renderSymbol(t,e){if(t.roomChar!==void 0){const s=new f.Text({x:0,y:0,text:t.roomChar,fontSize:.45,fontStyle:"bold",fill:this.mapReader.getSymbolColor(t.env),align:"center",verticalAlign:"middle",width:h.roomSize,height:h.roomSize});e.add(s)}}renderExits(t){t.forEach(e=>{const s=this.exitRenderer.render(e,this.currentZIndex);s&&(this.linkLayer.add(s),this.standaloneExitNodes.push(s),this.addStandaloneExitToSpatialIndex(s))})}renderLabels(t){t.forEach(e=>{if(h.labelRenderMode==="image"){if(!e.pixMap)return;const s=new Image;s.src=`data:image/png;base64,${e.pixMap}`;const i=new f.Image({x:e.X,y:-e.Y,width:e.Width,height:e.Height,image:s,listening:!1});this.linkLayer.add(i);return}this.renderLabelAsData(e)})}renderLabelAsData(t){var o;const e=new f.Group({listening:!1}),s=new f.Rect({x:t.X,y:-t.Y,width:t.Width,height:t.Height,listening:!1});(((o=t.BgColor)==null?void 0:o.alpha)??0)>0&&!h.transparentLabels?s.fill(this.getLabelColor(t.BgColor)):s.fillEnabled(!1),e.add(s);const i=Math.min(.75,t.Width/Math.max(t.Text.length/2,1)),r=Math.max(.1,Math.min(i,Math.max(t.Height*.9,.1))),n=new f.Text({x:t.X,y:-t.Y,width:t.Width,height:t.Height,text:t.Text,fontSize:r,fillEnabled:!0,fill:this.getLabelColor(t.FgColor),align:"center",verticalAlign:"middle",listening:!1});e.add(n),this.linkLayer.add(e)}getLabelColor(t){const e=((t==null?void 0:t.alpha)??255)/255,s=i=>Math.min(255,Math.max(0,i??0));return`rgba(${s(t==null?void 0:t.r)}, ${s(t==null?void 0:t.g)}, ${s(t==null?void 0:t.b)}, ${e})`}}const U={rgbValue:"rgb(114, 1, 0)",symbolColor:[225,225,225]};function J(g){const t=g[0]/255,e=g[1]/255,s=g[2]/255,i=Math.max(t,e,s),r=Math.min(t,e,s);return(i+r)/2}class yt{constructor(t,e){this.rooms={},this.areas={},this.areaSources={},this.explorationEnabled=!1,this.colors={},t.forEach(s=>{s.rooms.forEach(r=>{r.y=-r.y,this.rooms[r.id]=r});const i=parseInt(s.areaId);this.areas[i]=new $(s),this.areaSources[i]=s}),this.colors=e.reduce((s,i)=>({...s,[i.envId]:{rgb:i.colors,rgbValue:`rgb(${i.colors.join(",")})`,symbolColor:J(i.colors)>.41?[25,25,25]:[225,255,255],symbolColorValue:J(i.colors)>.41?"rgb(25,25,25)":"rgb(225,255,255)"}}),{})}getArea(t){return this.areas[t]}getExplorationArea(t){const e=this.areas[t];if(e instanceof Z)return e}getAreas(){return Object.values(this.areas)}getRooms(){return Object.values(this.rooms)}getRoom(t){return this.rooms[t]}ensureVisitedRooms(){return this.visitedRooms||(this.visitedRooms=new Set),this.visitedRooms}applyExplorationDecoration(){this.visitedRooms&&Object.entries(this.areaSources).forEach(([t,e])=>{const s=parseInt(t,10);this.areas[s]=new Z(e,this.visitedRooms)})}decorateWithExploration(t){return t!==void 0?this.setVisitedRooms(t):this.ensureVisitedRooms(),this.applyExplorationDecoration(),this.explorationEnabled=!0,this.visitedRooms}getVisitedRooms(){return this.visitedRooms}clearExplorationDecoration(){Object.entries(this.areaSources).forEach(([t,e])=>{const s=parseInt(t,10);this.areas[s]=new $(e)}),this.explorationEnabled=!1}isExplorationEnabled(){return this.explorationEnabled}setVisitedRooms(t){return this.visitedRooms=t instanceof Set?t:new Set(t),this.explorationEnabled&&this.applyExplorationDecoration(),this.visitedRooms}addVisitedRoom(t){if(this.explorationEnabled){const i=this.getRoom(t);if(i){const r=this.getExplorationArea(i.area);if(r)return r.addVisitedRoom(t)}}const e=this.ensureVisitedRooms(),s=e.has(t);return e.add(t),!s}addVisitedRooms(t){const e=this.ensureVisitedRooms();let s=0;for(const i of t){if(this.explorationEnabled){const n=this.getRoom(i);if(n){const o=this.getExplorationArea(n.area);if(o){o.addVisitedRoom(i)&&s++;continue}}}const r=e.has(i);e.add(i),r||s++}return s}hasVisitedRoom(t){var e;return((e=this.visitedRooms)==null?void 0:e.has(t))??!1}getColorValue(t){var e;return((e=this.colors[t])==null?void 0:e.rgbValue)??U.rgbValue}getSymbolColor(t,e){var n;const s=((n=this.colors[t])==null?void 0:n.symbolColor)??U.symbolColor,i=Math.min(Math.max(e??1,0),1),r=s.join(",");return i!=1?`rgba(${r}, ${i})`:`rgba(${r})`}}function Rt(g){return g&&g.__esModule&&Object.prototype.hasOwnProperty.call(g,"default")?g.default:g}class wt{constructor(){this.keys=new Set,this.queue=[]}sort(){this.queue.sort((t,e)=>t.priority-e.priority)}set(t,e){const s=Number(e);if(isNaN(s))throw new TypeError('"priority" must be a number');return this.keys.has(t)?this.queue.map(i=>(i.key===t&&Object.assign(i,{priority:s}),i)):(this.keys.add(t),this.queue.push({key:t,priority:s})),this.sort(),this.queue.length}next(){const t=this.queue.shift();return this.keys.delete(t.key),t}isEmpty(){return this.queue.length===0}has(t){return this.keys.has(t)}get(t){return this.queue.find(e=>e.key===t)}}var vt=wt;function ot(g,t){const e=new Map;for(const[s,i]of g)s!==t&&i instanceof Map?e.set(s,ot(i,t)):s!==t&&e.set(s,i);return e}var Et=ot;function St(g){const t=Number(g);return!(isNaN(t)||t<=0)}function nt(g){const t=new Map;return Object.keys(g).forEach(s=>{const i=g[s];if(i!==null&&typeof i=="object"&&!Array.isArray(i))return t.set(s,nt(i));if(!St(i))throw new Error(`Could not add node at key "${s}", make sure it's a valid node`,i);return t.set(s,Number(i))}),t}var Dt=nt;function at(g){if(!(g instanceof Map))throw new Error(`Invalid graph: Expected Map instead found ${typeof g}`);g.forEach((t,e)=>{if(typeof t=="object"&&t instanceof Map){at(t);return}if(typeof t!="number"||t<=0)throw new Error(`Values must be numbers greater than 0. Found value ${t} at ${e}`)})}var Ct=at;const Lt=vt,Mt=Et,tt=Dt,et=Ct;class kt{constructor(t){t instanceof Map?(et(t),this.graph=t):t?this.graph=tt(t):this.graph=new Map}addNode(t,e){let s;return e instanceof Map?(et(e),s=e):s=tt(e),this.graph.set(t,s),this}addVertex(t,e){return this.addNode(t,e)}removeNode(t){return this.graph=Mt(this.graph,t),this}path(t,e,s={}){if(!this.graph.size)return s.cost?{path:null,cost:0}:null;const i=new Set,r=new Lt,n=new Map;let o=[],a=0,d=[];if(s.avoid&&(d=[].concat(s.avoid)),d.includes(t))throw new Error(`Starting node (${t}) cannot be avoided`);if(d.includes(e))throw new Error(`Ending node (${e}) cannot be avoided`);for(r.set(t,0);!r.isEmpty();){const u=r.next();if(u.key===e){a=u.priority;let y=u.key;for(;n.has(y);)o.push(y),y=n.get(y);break}i.add(u.key),(this.graph.get(u.key)||new Map).forEach((y,l)=>{if(i.has(l)||d.includes(l))return null;if(!r.has(l))return n.set(l,u.key),r.set(l,u.priority+y);const m=r.get(l).priority,w=u.priority+y;return w<m?(n.set(l,u.key),r.set(l,w)):null})}return o.length?(s.trim?o.shift():o=o.concat([t]),s.reverse||(o=o.reverse()),s.cost?{path:o,cost:a}:o):s.cost?{path:null,cost:0}:null}shortestPath(...t){return this.path(...t)}}var It=kt;const zt=Rt(It),Ot={1:"north",2:"northeast",3:"northwest",4:"east",5:"west",6:"south",7:"southeast",8:"southwest",9:"up",10:"down",11:"in",12:"out"};class Vt{constructor(t){this.cache=new Map,this.mapReader=t,this.graph=this.buildGraph()}buildGraph(){const t={};return this.mapReader.getRooms().forEach(e=>{const s={},i=new Set((e.exitLocks??[]).map(n=>Ot[n]).filter(n=>!!n)),r=new Set(e.mSpecialExitLocks??[]);Object.entries(e.exits??{}).forEach(([n,o])=>{i.has(n)||this.mapReader.getRoom(o)&&(s[o.toString()]=1)}),Object.values(e.specialExits??{}).forEach(n=>{r.has(n)||this.mapReader.getRoom(n)&&(s[n.toString()]=1)}),t[e.id.toString()]=s}),new zt(t)}findPath(t,e){const s=`${t}->${e}`;if(this.cache.has(s))return this.cache.get(s);if(t===e){const o=this.mapReader.getRoom(t)?[t]:null;return this.cache.set(s,o),o}if(!this.mapReader.getRoom(t)||!this.mapReader.getRoom(e))return this.cache.set(s,null),null;const i=this.graph.path(t.toString(),e.toString()),r=Array.isArray(i)?i:i==null?void 0:i.path,n=r?r.map(o=>Number(o)):null;return this.cache.set(s,n),n}}exports.ExplorationArea=Z;exports.MapReader=yt;exports.PathFinder=Vt;exports.Renderer=xt;exports.Settings=h;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|