1
0
mirror of https://github.com/teoxoy/factorio-blueprint-editor.git synced 2025-03-27 21:39:03 +02:00

Implement constrained click and drag that doesn't leave spaces (#241)

This commit is contained in:
KenCoder 2022-04-19 04:58:24 -04:00 committed by GitHub
parent 9748ecf88b
commit 8c58aa765c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 91 additions and 18 deletions

View File

@ -287,12 +287,8 @@ export class Editor {
})
registerAction('build', 'lclick').bind({
press: () => {
if (G.BPC.mode === EditorMode.PAINT) {
G.BPC.paintContainer.placeEntityContainer()
}
},
repeat: true,
press: () => G.BPC.enterDraggingCreateMode(),
release: () => G.BPC.exitDraggingCreateMode(),
})
registerAction('mine', 'rclick').bind({

View File

@ -86,6 +86,7 @@ export class BlueprintContainer extends PIXI.Container {
private deleteModeEntities: Entity[] = []
private copyModeUpdateFn: (endX: number, endY: number) => void
private deleteModeUpdateFn: (endX: number, endY: number) => void
private draggingCreateUpdateFn: () => void
public viewportCulling = true
@ -316,6 +317,27 @@ export class BlueprintContainer extends PIXI.Container {
this.copyModeEntities = []
}
public enterDraggingCreateMode(): void {
if (this.mode !== EditorMode.PAINT) return
if (this.draggingCreateUpdateFn !== undefined) return
this.paintContainer.placeEntityContainer()
this.gridData.constrained = true
this.draggingCreateUpdateFn = () => {
this.paintContainer.placeEntityContainer()
}
this.gridData.on('update32', this.draggingCreateUpdateFn)
}
public exitDraggingCreateMode(): void {
if (this.draggingCreateUpdateFn === undefined) return
this.gridData.constrained = false
this.gridData.off('update32', this.draggingCreateUpdateFn)
this.draggingCreateUpdateFn = undefined
}
public enterDeleteMode(): void {
if (this.mode === EditorMode.DELETE) return
if (this.mode === EditorMode.PAINT) this.paintContainer.destroy()

View File

@ -11,6 +11,9 @@ export class GridData extends EventEmitter {
private _x32 = 0
private _y32 = 0
private _constrained = false
private _constrainTo: 'x' | 'y' | undefined = undefined
private lastMousePosX = 0
private lastMousePosY = 0
@ -48,6 +51,15 @@ export class GridData extends EventEmitter {
return this._y32
}
public get constrained(): boolean {
return this._constrained
}
public set constrained(constrained: boolean) {
this._constrained = constrained
this._constrainTo = undefined
}
public destroy(): void {
this.emit('destroy')
}
@ -56,9 +68,36 @@ export class GridData extends EventEmitter {
this.update(this.lastMousePosX, this.lastMousePosY)
}
private constrainMove(element: '_x16' | '_y16' | '_x32' | '_y32', target: number): boolean {
if (!this.constrained) {
this[element] = target
return false
}
if (this._constrainTo === undefined) {
return false
}
if (element.startsWith(`_${ this._constrainTo}`)) {
const sign = Math.sign(target - this[element])
this[element] += sign
return this[element] != target
}
}
private updateValuesWithConstraints(x16: number, y16: number, x32: number, y32: number): boolean {
let anythingChanged = false
if (this.constrainMove('_x16', x16)) anythingChanged = true
if (this.constrainMove('_y16', y16)) anythingChanged = true
if (this.constrainMove('_x32', x32)) anythingChanged = true
if (this.constrainMove('_y32', y32)) anythingChanged = true
return anythingChanged
}
private update(mouseX: number, mouseY: number): void {
if (!this.bpc) return
if (this.bpc.mode === EditorMode.PAN) return
this.lastMousePosX = mouseX
this.lastMousePosY = mouseY
@ -70,27 +109,43 @@ export class GridData extends EventEmitter {
const oldX16 = this._x16
const oldY16 = this._y16
this._x16 = Math.floor(this._x / 16)
this._y16 = Math.floor(this._y / 16)
const oldX32 = this._x32
const oldY32 = this._y32
this._x32 = Math.floor(this._x / 32)
this._y32 = Math.floor(this._y / 32)
if (this.bpc.mode === EditorMode.PAN) return
const x16 = Math.floor(this._x / 16)
const y16 = Math.floor(this._y / 16)
const x32 = Math.floor(this._x / 32)
const y32 = Math.floor(this._y / 32)
if (this._constrained && this._constrainTo === undefined) {
const deltaX = Math.abs(x16 - oldX16)
const deltaY = Math.abs(y16 - oldY16)
if (deltaX > 0 && deltaX > deltaY) {
this._constrainTo = 'x'
} else if (deltaY > 0) {
this._constrainTo = 'y'
}
}
// emit update when mouse changes tile whithin the 1 pixel size grid
if (!(oldX === this._x && oldY === this._y)) {
this.emit('update', this._x, this._y)
}
// emit update16 when mouse changes tile whithin the 16 pixel size grid
if (!(oldX16 === this._x16 && oldY16 === this._y16)) {
this.emit('update16', this._x16, this._y16)
}
// emit update32 when mouse changes tile whithin the 32 pixel size grid
if (!(oldX32 === this._x32 && oldY32 === this._y32)) {
this.emit('update32', this._x32, this._y32)
let more = true
while (more) {
more = this.updateValuesWithConstraints(x16, y16, x32, y32)
// emit update16 when mouse changes tile whithin the 16 pixel size grid
if (!(oldX16 === this._x16 && oldY16 === this._y16)) {
this.emit('update16', this._x16, this._y16)
}
// emit update32 when mouse changes tile whithin the 32 pixel size grid
if (!(oldX32 === this._x32 && oldY32 === this._y32)) {
this.emit('update32', this._x32, this._y32)
}
}
}
}