91 lines
2.7 KiB
TypeScript
91 lines
2.7 KiB
TypeScript
|
|
import {
|
|||
|
|
type MapAreaInfo,
|
|||
|
|
MapAreaType,
|
|||
|
|
type MapPen,
|
|||
|
|
MapPointType,
|
|||
|
|
type Point,
|
|||
|
|
} from '@api/map';
|
|||
|
|
import { LockState, s8 } from '@meta2d/core';
|
|||
|
|
|
|||
|
|
import type { EditorService } from '../editor.service';
|
|||
|
|
import type { AutoStorageGenerator } from '../utils/auto-storage-generator';
|
|||
|
|
|
|||
|
|
export class AreaManager {
|
|||
|
|
constructor(
|
|||
|
|
private readonly editor: EditorService,
|
|||
|
|
private readonly autoStorageGenerator: AutoStorageGenerator,
|
|||
|
|
) {}
|
|||
|
|
|
|||
|
|
public getBoundAreas(id: string, name: 'point' | 'line', type: MapAreaType): MapPen[] {
|
|||
|
|
if (!id) return [];
|
|||
|
|
return this.editor.find(`area-${type}`).filter(({ area }) => {
|
|||
|
|
if (name === 'point') return area?.points?.includes(id);
|
|||
|
|
if (name === 'line') return area?.routes?.includes(id);
|
|||
|
|
return false;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async addArea(p1: Point, p2: Point, type = MapAreaType.库区, id?: string): Promise<void> {
|
|||
|
|
const w = Math.abs(p1.x - p2.x);
|
|||
|
|
const h = Math.abs(p1.y - p2.y);
|
|||
|
|
if (w < 50 || h < 60) return;
|
|||
|
|
|
|||
|
|
const points: string[] = [];
|
|||
|
|
const routes: string[] = [];
|
|||
|
|
|
|||
|
|
if (!id) {
|
|||
|
|
id = s8();
|
|||
|
|
const selected = this.editor.store.active as MapPen[] | undefined;
|
|||
|
|
switch (type) {
|
|||
|
|
case MapAreaType.库区:
|
|||
|
|
selected
|
|||
|
|
?.filter(({ point }) => point?.type === MapPointType.动作点)
|
|||
|
|
.forEach(({ id: pointId }) => points.push(pointId!));
|
|||
|
|
break;
|
|||
|
|
case MapAreaType.互斥区:
|
|||
|
|
case MapAreaType.非互斥区:
|
|||
|
|
case MapAreaType.约束区:
|
|||
|
|
selected?.filter(({ point }) => point?.type).forEach(({ id: pointId }) => points.push(pointId!));
|
|||
|
|
break;
|
|||
|
|
case MapAreaType.描述区:
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const areaInfo: MapAreaInfo = { type, points, routes };
|
|||
|
|
if (type === MapAreaType.库区) {
|
|||
|
|
areaInfo.inoutflag = 2;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const pen: MapPen = {
|
|||
|
|
id,
|
|||
|
|
name: 'area',
|
|||
|
|
tags: ['area', `area-${type}`],
|
|||
|
|
label: `A${id}`,
|
|||
|
|
x: Math.min(p1.x, p2.x),
|
|||
|
|
y: Math.min(p1.y, p2.y),
|
|||
|
|
width: w,
|
|||
|
|
height: h,
|
|||
|
|
lineWidth: 1,
|
|||
|
|
area: areaInfo,
|
|||
|
|
locked: LockState.None,
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const area = await this.editor.addPen(pen, true, true, true);
|
|||
|
|
this.editor.bottom(area);
|
|||
|
|
|
|||
|
|
if (type === MapAreaType.库区 && points.length > 0) {
|
|||
|
|
this.autoStorageGenerator.triggerAutoCreateStorageDialog(pen, points);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public updateArea(id: string, info: Partial<MapAreaInfo>): void {
|
|||
|
|
const { area } = this.editor.getPenById(id) ?? {};
|
|||
|
|
if (!area?.type) return;
|
|||
|
|
const mergedArea = { ...area, ...info };
|
|||
|
|
this.editor.setValue({ id, area: mergedArea }, { render: true, history: true, doEvent: true });
|
|||
|
|
}
|
|||
|
|
}
|