@@ -7,58 +7,127 @@ import { Server } from "@notbeer-api";
77import { PatternUIBuilder } from "editor/pane/pattern" ;
88import { MaskUIBuilder } from "editor/pane/mask" ;
99import { Mask } from "@modules/mask" ;
10+ import { Cardinal } from "@modules/directions" ;
11+
12+ enum RegionOperatorMode {
13+ Fill ,
14+ Outline ,
15+ Wall ,
16+ Stack ,
17+ Move ,
18+ }
19+
20+ const directions = Object . keys ( Cardinal . Dir ) ;
21+ // Object.keys on an enum returns not just the enumerators, but there number equivalent.
22+ // Removing those with splice()
23+ directions . splice ( 0 , directions . length / 2 ) ;
1024
1125export class RegionOpModule extends EditorModule {
1226 private pane : UIPane ;
27+ private readonly patternUIBuilder = new PatternUIBuilder ( new Pattern ( "stone" ) ) ;
28+ private readonly maskUIBuilder = new MaskUIBuilder ( new Mask ( "air" ) ) ;
29+ private enableMask = false ;
30+ private direction = Cardinal . Dir . FORWARD ;
31+ private distance = 5 ;
32+ private stackCount = 1 ;
33+ private mode = 0 ;
1334
1435 constructor ( session : IPlayerUISession ) {
1536 super ( session ) ;
1637 const tool = session . toolRail . addTool ( "worldedit:region_operations" , { title : "WorldEdit Region Operations" } ) ;
17- const patternUIBuilder = new PatternUIBuilder ( new Pattern ( "stone" ) ) ;
18- const maskUIBuilder = new MaskUIBuilder ( new Mask ( "air" ) ) ;
19- let enableMask = false ;
20- let mode = 0 ;
2138
2239 this . pane = new UIPane ( this . session , {
2340 title : "Region Operations" ,
2441 items : [
2542 {
2643 type : "dropdown" ,
2744 title : "Mode" ,
28- value : mode ,
45+ value : this . mode ,
2946 entries : [
30- { label : "Fill Selection" , value : 0 } ,
31- { label : "Outline Selection" , value : 1 } ,
32- { label : "Wall Selection" , value : 2 } ,
47+ { label : "Fill Selection" , value : RegionOperatorMode . Fill } ,
48+ { label : "Outline Selection" , value : RegionOperatorMode . Outline } ,
49+ { label : "Wall Selection" , value : RegionOperatorMode . Wall } ,
50+ { label : "Stack Selection" , value : RegionOperatorMode . Stack } ,
51+ { label : "Move Selection" , value : RegionOperatorMode . Move } ,
3352 ] ,
3453 onChange : ( value ) => {
35- mode = value ;
36- const usePatternAndMask = mode >= 0 && mode <= 2 ;
37- this . pane . getSubPane ( "pattern" ) . visible = usePatternAndMask ;
38- this . pane . getSubPane ( "mask" ) . visible = usePatternAndMask ;
54+ this . mode = value ;
55+ this . updatePane ( ) ;
3956 } ,
4057 } ,
4158 {
4259 type : "button" ,
4360 title : "Execute Operation" ,
4461 enable : this . canOperate ( ) ,
4562 pressed : ( ) => {
46- const mode = this . pane . getValue ( 0 ) as number ;
47- if ( mode >= 0 && mode <= 2 ) {
63+ if ( this . usesPatternAndMask ( ) ) {
4864 const args = new Map < string , any > ( [
49- [ "pattern" , patternUIBuilder . pattern ] ,
50- [ "mask" , enableMask ? maskUIBuilder . mask : new Mask ( ) ] ,
65+ [ "pattern" , this . patternUIBuilder . pattern ] ,
66+ [ "mask" , this . enableMask ? this . maskUIBuilder . mask : new Mask ( ) ] ,
5167 ] ) ;
52- const command = mode === 0 ? "replace" : mode === 1 ? "faces" : mode === 2 ? "walls" : "" ;
68+ const command = {
69+ [ RegionOperatorMode . Fill ] : "replace" ,
70+ [ RegionOperatorMode . Outline ] : "faces" ,
71+ [ RegionOperatorMode . Wall ] : "walls" ,
72+ } [ this . mode ] ;
5373 Server . command . getRegistration ( command ) . callback ( this . player , "editor-callback" , args ) ;
74+ } else if ( this . mode === RegionOperatorMode . Stack ) {
75+ Server . command . getRegistration ( "stack" ) . callback (
76+ this . player ,
77+ "editor-callback" ,
78+ new Map (
79+ Object . entries ( {
80+ a : true ,
81+ count : this . stackCount ,
82+ offset : new Cardinal ( this . direction ) ,
83+ } )
84+ )
85+ ) ;
86+ } else if ( this . mode === RegionOperatorMode . Move ) {
87+ Server . command . getRegistration ( "move" ) . callback (
88+ this . player ,
89+ "editor-callback" ,
90+ new Map (
91+ Object . entries ( {
92+ a : true ,
93+ amount : this . distance ,
94+ offset : new Cardinal ( this . direction ) ,
95+ } )
96+ )
97+ ) ;
5498 }
5599 } ,
56100 } ,
101+ { type : "divider" } ,
102+ {
103+ type : "dropdown" ,
104+ title : "Direction" ,
105+ uniqueId : "direction" ,
106+ entries : directions . map ( ( dir , index ) => ( { label : dir , value : index } ) ) ,
107+ value : Cardinal . Dir . FORWARD ,
108+ onChange : ( value ) => ( this . direction = value ) ,
109+ } ,
110+ {
111+ type : "slider" ,
112+ title : "Distance" ,
113+ uniqueId : "distance" ,
114+ min : 1 ,
115+ value : 5 ,
116+ onChange : ( value ) => ( this . distance = value ) ,
117+ } ,
118+ {
119+ type : "slider" ,
120+ title : "Stack Count" ,
121+ uniqueId : "stackCount" ,
122+ min : 1 ,
123+ value : 1 ,
124+ onChange : ( value ) => ( this . stackCount = value ) ,
125+ } ,
57126 {
58127 type : "subpane" ,
59128 title : "Pattern" ,
60129 uniqueId : "pattern" ,
61- items : patternUIBuilder ,
130+ items : this . patternUIBuilder ,
62131 } ,
63132 {
64133 type : "subpane" ,
@@ -68,11 +137,11 @@ export class RegionOpModule extends EditorModule {
68137 {
69138 type : "toggle" ,
70139 title : "Enable Mask" ,
71- value : enableMask ,
140+ value : this . enableMask ,
72141 onChange : ( value ) => {
73- enableMask = value ;
142+ this . enableMask = value ;
74143 const pane = this . pane . getSubPane ( "mask" ) . getSubPane ( 1 ) ;
75- if ( value ) maskUIBuilder . build ( pane ) ;
144+ if ( value ) this . maskUIBuilder . build ( pane ) ;
76145 else pane . changeItems ( [ ] ) ;
77146 } ,
78147 } ,
@@ -88,6 +157,19 @@ export class RegionOpModule extends EditorModule {
88157 } ) ;
89158 this . pane . bindToTool ( tool ) ;
90159 this . session . extensionContext . afterEvents . SelectionChange . subscribe ( this . onSelectionChange ) ;
160+ this . updatePane ( ) ;
161+ }
162+
163+ private updatePane ( ) {
164+ this . pane . getSubPane ( "pattern" ) . visible = this . usesPatternAndMask ( ) ;
165+ this . pane . getSubPane ( "mask" ) . visible = this . usesPatternAndMask ( ) ;
166+ this . pane . setVisibility ( "direction" , this . mode === RegionOperatorMode . Stack || this . mode === RegionOperatorMode . Move ) ;
167+ this . pane . setVisibility ( "distance" , this . mode === RegionOperatorMode . Move ) ;
168+ this . pane . setVisibility ( "stackCount" , this . mode === RegionOperatorMode . Stack ) ;
169+ }
170+
171+ private usesPatternAndMask ( ) {
172+ return this . mode === RegionOperatorMode . Fill || this . mode === RegionOperatorMode . Outline || this . mode === RegionOperatorMode . Wall ;
91173 }
92174
93175 private canOperate ( ) {
0 commit comments