Path: blob/master/src/editor/modules/selection.ts
1784 views
import { EditorModule } from "./base";1import { Player, system } from "@minecraft/server";2import { IPlayerUISession, SelectionContainerVolume, SelectionManager } from "@minecraft/server-editor";3import { DefaultSelection, setSelectionClass } from "@modules/selection";4import { Vector } from "@notbeer-api";5import { VolumeShape } from "editor/shapes/volume";6import { shapeToBlockVolume } from "editor/util";7import { getSession } from "server/sessions";89const selections = new WeakMap<Player, SelectionManager>();10const ignoreSelectionUpdates = new WeakMap<Player, number>();1112function ignoreSelectionUpdate(player: Player) {13if (ignoreSelectionUpdates.has(player)) system.clearRun(ignoreSelectionUpdates.get(player));14ignoreSelectionUpdates.set(15player,16system.runTimeout(() => ignoreSelectionUpdates.delete(player), 2)17);18}1920class EditorSelection extends DefaultSelection {21private volumeUpdator = shapeToBlockVolume();2223public updateVolumeShape() {24this.set(0, Vector.ZERO);25this.set(1, Vector.ZERO);26this.shape = [new VolumeShape(this.volume.get()), Vector.ZERO];27}2829protected updateShape() {30super.updateShape();3132if (this.mode === "volume") return;3334const [shape, location] = this.getShape() ?? [undefined, undefined];35this.volumeUpdator.update(shape, (volume) => {36if (!volume) {37this.volume.clear();38} else {39volume.translate(location);40this.volume.set(volume);41}42ignoreSelectionUpdate(this.player);43});44}4546private get volume(): SelectionContainerVolume {47return selections.get(this.player)?.volume;48}49}50setSelectionClass(EditorSelection);5152export class SelectionModule extends EditorModule {53constructor(session: IPlayerUISession) {54super(session);55const selection = this.session.extensionContext.selectionManager;56selections.set(this.player, selection);5758this.session.extensionContext.afterEvents.SelectionChange.subscribe(() => {59if (ignoreSelectionUpdates.has(this.player)) return;6061const worldEditSelection = getSession(this.player).selection as EditorSelection;62if (selection.volume.isEmpty) {63worldEditSelection.clear();64} else if (selection.volume.volumeCount === 1) {65if (!worldEditSelection.isCuboid) worldEditSelection.mode = "cuboid";66const { min, max } = selection.volume.getBoundingBox();67worldEditSelection.set(0, Vector.from(min));68worldEditSelection.set(1, Vector.from(max));69} else {70if (worldEditSelection.mode !== "volume") {71worldEditSelection.mode = "volume";72worldEditSelection.updateVolumeShape();73}74}75});76}7778teardown() {79selections.delete(this.player);80}81}828384