2014-04-03 02:08:50 +00:00
/ *
2014-04-04 22:03:18 +00:00
* WorldEdit , a Minecraft world manipulation toolkit
* Copyright ( C ) sk89q < http : //www.sk89q.com>
* Copyright ( C ) WorldEdit team and contributors
2014-04-03 02:08:50 +00:00
*
2014-04-04 22:03:18 +00:00
* This program is free software : you can redistribute it and / or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation , either version 3 of the License , or
2014-04-03 02:08:50 +00:00
* ( at your option ) any later version .
*
2014-04-04 22:03:18 +00:00
* This program is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU Lesser General Public License
* for more details .
2014-04-03 02:08:50 +00:00
*
2014-04-04 22:03:18 +00:00
* You should have received a copy of the GNU Lesser General Public License
2014-04-03 02:08:50 +00:00
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
2014-04-04 22:03:18 +00:00
* /
2014-04-03 02:08:50 +00:00
package com.sk89q.worldedit.command ;
2019-12-11 22:46:47 +00:00
import static com.sk89q.worldedit.command.util.Logging.LogMode.ALL ;
import static com.sk89q.worldedit.command.util.Logging.LogMode.ORIENTATION_REGION ;
import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION ;
import static com.sk89q.worldedit.internal.command.CommandUtil.checkCommandArgument ;
import static com.sk89q.worldedit.regions.Regions.asFlatRegion ;
import static com.sk89q.worldedit.regions.Regions.maximumBlockY ;
import static com.sk89q.worldedit.regions.Regions.minimumBlockY ;
2018-08-12 14:03:07 +00:00
import com.boydti.fawe.FaweAPI ;
2019-10-23 14:35:04 +00:00
import com.boydti.fawe.FaweCache ;
2018-08-12 14:03:07 +00:00
import com.boydti.fawe.object.FaweLimit ;
import com.sk89q.jnbt.CompoundTag ;
2018-12-23 16:19:33 +00:00
import com.sk89q.worldedit.EditSession ;
import com.sk89q.worldedit.LocalSession ;
import com.sk89q.worldedit.WorldEditException ;
2019-07-06 00:46:48 +00:00
import com.sk89q.worldedit.command.util.CommandPermissions ;
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator ;
import com.sk89q.worldedit.command.util.Logging ;
2019-12-11 22:46:47 +00:00
import com.sk89q.worldedit.command.util.annotation.Confirm ;
2014-06-28 08:01:49 +00:00
import com.sk89q.worldedit.entity.Player ;
2019-07-23 23:17:38 +00:00
import com.sk89q.worldedit.extension.platform.Actor ;
2014-06-28 08:01:49 +00:00
import com.sk89q.worldedit.function.GroundFunction ;
import com.sk89q.worldedit.function.generator.FloraGenerator ;
2014-04-03 02:08:50 +00:00
import com.sk89q.worldedit.function.mask.ExistingBlockMask ;
2014-06-28 08:01:49 +00:00
import com.sk89q.worldedit.function.mask.Mask ;
2019-12-11 22:46:47 +00:00
import com.sk89q.worldedit.function.mask.MaskIntersection ;
2014-06-28 08:01:49 +00:00
import com.sk89q.worldedit.function.mask.NoiseFilter2D ;
2019-07-18 06:56:57 +00:00
import com.sk89q.worldedit.function.mask.SolidBlockMask ;
2014-04-03 02:08:50 +00:00
import com.sk89q.worldedit.function.operation.Operations ;
2014-06-28 08:01:49 +00:00
import com.sk89q.worldedit.function.pattern.Pattern ;
import com.sk89q.worldedit.function.visitor.LayerVisitor ;
import com.sk89q.worldedit.internal.annotation.Direction ;
import com.sk89q.worldedit.internal.annotation.Selection ;
import com.sk89q.worldedit.internal.expression.ExpressionException ;
2019-04-03 13:25:16 +00:00
import com.sk89q.worldedit.math.BlockVector2 ;
2018-12-23 16:19:33 +00:00
import com.sk89q.worldedit.math.BlockVector3 ;
import com.sk89q.worldedit.math.Vector3 ;
2014-04-03 02:08:50 +00:00
import com.sk89q.worldedit.math.convolution.GaussianKernel ;
import com.sk89q.worldedit.math.convolution.HeightMap ;
import com.sk89q.worldedit.math.convolution.HeightMapFilter ;
2014-06-28 08:01:49 +00:00
import com.sk89q.worldedit.math.noise.RandomNoise ;
2019-06-30 18:56:32 +00:00
import com.sk89q.worldedit.regions.ConvexPolyhedralRegion ;
import com.sk89q.worldedit.regions.CuboidRegion ;
import com.sk89q.worldedit.regions.Region ;
import com.sk89q.worldedit.regions.RegionOperationException ;
import com.sk89q.worldedit.regions.Regions ;
2018-08-12 14:03:07 +00:00
import com.sk89q.worldedit.util.Location ;
2014-06-28 08:01:49 +00:00
import com.sk89q.worldedit.util.TreeGenerator.TreeType ;
2019-12-11 22:46:47 +00:00
import com.sk89q.worldedit.util.formatting.text.TextComponent ;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent ;
2019-07-23 23:17:38 +00:00
import com.sk89q.worldedit.world.World ;
2019-04-03 13:25:16 +00:00
import com.sk89q.worldedit.world.biome.BiomeType ;
import com.sk89q.worldedit.world.block.BlockStateHolder ;
2019-10-30 11:26:52 +00:00
import com.sk89q.worldedit.world.block.BlockTypes ;
2019-12-11 22:46:47 +00:00
import java.util.ArrayList ;
import java.util.Iterator ;
import java.util.List ;
2019-07-06 00:46:48 +00:00
import org.enginehub.piston.annotation.Command ;
import org.enginehub.piston.annotation.CommandContainer ;
import org.enginehub.piston.annotation.param.Arg ;
2019-08-06 15:25:53 +00:00
import org.enginehub.piston.annotation.param.ArgFlag ;
2019-07-06 00:46:48 +00:00
import org.enginehub.piston.annotation.param.Switch ;
2019-11-20 00:11:54 +00:00
import org.jetbrains.annotations.Range ;
2014-04-03 02:08:50 +00:00
/ * *
2014-06-28 08:01:49 +00:00
* Commands that operate on regions .
2014-04-03 02:08:50 +00:00
* /
2019-07-06 00:46:48 +00:00
@CommandContainer ( superTypes = CommandPermissionsConditionGenerator . Registration . class )
2019-07-23 23:17:38 +00:00
public class RegionCommands {
2014-04-03 02:08:50 +00:00
2014-06-28 08:01:49 +00:00
/ * *
* Create a new instance .
* /
2019-04-24 01:46:46 +00:00
public RegionCommands ( ) {
2014-04-03 02:08:50 +00:00
}
2019-04-26 06:16:18 +00:00
@Command (
2019-11-20 03:40:52 +00:00
name = " /set " ,
aliases = { " / " } ,
desc = " Sets all the blocks in the region "
2019-04-26 06:16:18 +00:00
)
@CommandPermissions ( " worldedit.region.set " )
@Logging ( REGION )
2019-11-21 06:50:37 +00:00
@Confirm ( Confirm . Processor . REGION )
2019-08-25 09:58:28 +00:00
public int set ( Actor actor , EditSession editSession ,
2019-04-26 06:16:18 +00:00
@Selection Region region ,
2019-05-26 06:20:02 +00:00
@Arg ( desc = " The pattern of blocks to set " )
2019-11-21 06:50:37 +00:00
Pattern pattern ) {
int affected = editSession . setBlocks ( region , pattern ) ;
if ( affected ! = 0 ) {
2019-10-13 11:47:26 +00:00
actor . printInfo ( TranslatableComponent . of ( " worldedit.set.done " ) ) ;
2019-11-21 06:50:37 +00:00
if ( ! actor . hasPermission ( " fawe.tips " ) )
2019-11-21 19:56:10 +00:00
System . out . println ( " TODO FIXME TIPS " ) ;
// TranslatableComponent.of("fawe.tips.tip.fast").or(TranslatableComponent.of("fawe.tips.tip.cancel"), TranslatableComponent.of("fawe.tips.tip.mask"), TranslatableComponent.of("fawe.tips.tip.mask.angle"), TranslatableComponent.of("fawe.tips.tip.set.linear"), TranslatableComponent.of("fawe.tips.tip.surface.spread"), TranslatableComponent.of("fawe.tips.tip.set.hand")).send(actor);
2019-11-21 06:50:37 +00:00
}
2019-11-20 03:40:52 +00:00
return 0 ;
2014-04-03 02:08:50 +00:00
}
2019-07-25 18:44:10 +00:00
@Command (
2019-10-30 11:26:52 +00:00
name = " /air " ,
aliases = { " /0 " } ,
desc = " Sets all the blocks in the region to air "
)
@CommandPermissions ( " worldedit.region.set " )
@Logging ( REGION )
2019-11-21 06:50:37 +00:00
public void air ( Actor actor , EditSession editSession , @Selection Region region ) throws WorldEditException {
set ( actor , editSession , region , BlockTypes . AIR ) ;
2019-10-30 11:26:52 +00:00
}
@Command (
name = " /test " ,
desc = " test region "
)
@CommandPermissions ( " worldedit.region.test " )
@Logging ( REGION )
2019-11-22 17:11:20 +00:00
public void test ( Player player , EditSession editSession , @Arg ( desc = " test " ) String worldName , BlockVector2 mcaFile ) throws WorldEditException {
2019-11-22 15:37:15 +00:00
// file = new File(world, "region" + File.separator)
2019-11-22 15:30:45 +00:00
2019-10-30 11:26:52 +00:00
}
2014-04-03 02:08:50 +00:00
@Command (
2019-07-06 00:46:48 +00:00
name = " /fixlighting " ,
desc = " Get the light at a position "
2018-08-12 14:03:07 +00:00
)
@CommandPermissions ( " worldedit.light.fix " )
2019-07-23 23:17:38 +00:00
public void fixLighting ( Player player ) throws WorldEditException {
2019-06-06 01:17:34 +00:00
final Location loc = player . getLocation ( ) ;
2019-09-14 03:05:16 +00:00
Region selection = player . getSelection ( ) ;
2018-08-12 14:03:07 +00:00
if ( selection = = null ) {
2019-06-06 01:17:34 +00:00
final int cx = loc . getBlockX ( ) > > 4 ;
final int cz = loc . getBlockZ ( ) > > 4 ;
2018-10-19 20:13:32 +00:00
selection = new CuboidRegion ( BlockVector3 . at ( cx - 8 , 0 , cz - 8 ) . multiply ( 16 ) , BlockVector3 . at ( cx + 8 , 0 , cz + 8 ) . multiply ( 16 ) ) ;
2018-08-12 14:03:07 +00:00
}
2019-07-21 11:39:36 +00:00
int count = FaweAPI . fixLighting ( player . getWorld ( ) , selection , null ) ;
2019-11-21 19:56:10 +00:00
player . print ( TranslatableComponent . of ( " fawe.info.lighting.propagate.selection " , count ) ) ;
2018-08-12 14:03:07 +00:00
}
@Command (
2019-07-06 00:46:48 +00:00
name = " /getlighting " ,
desc = " Get the light at a position "
2018-08-12 14:03:07 +00:00
)
@CommandPermissions ( " worldedit.light.fix " )
2019-07-23 23:17:38 +00:00
public void getLighting ( Player player , EditSession editSession ) throws WorldEditException {
2019-06-06 01:17:34 +00:00
final Location loc = player . getLocation ( ) ;
2019-07-21 11:39:36 +00:00
int block = editSession . getBlockLight ( loc . getBlockX ( ) , loc . getBlockY ( ) , loc . getBlockZ ( ) ) ;
int sky = editSession . getSkyLight ( loc . getBlockX ( ) , loc . getBlockY ( ) , loc . getBlockZ ( ) ) ;
2019-09-14 03:05:16 +00:00
player . print ( " Light: " + block + " | " + sky ) ;
2018-08-12 14:03:07 +00:00
}
@Command (
2019-07-06 00:46:48 +00:00
name = " /removelighting " ,
desc = " Removing lighting in a selection "
2018-08-12 14:03:07 +00:00
)
@CommandPermissions ( " worldedit.light.remove " )
2019-07-23 23:17:38 +00:00
public void removeLighting ( Player player ) {
2019-09-14 03:05:16 +00:00
Region selection = player . getSelection ( ) ;
2018-08-12 14:03:07 +00:00
if ( selection = = null ) {
2019-06-06 01:17:34 +00:00
final int cx = player . getLocation ( ) . getBlockX ( ) > > 4 ;
final int cz = player . getLocation ( ) . getBlockZ ( ) > > 4 ;
2018-10-19 20:13:32 +00:00
selection = new CuboidRegion ( BlockVector3 . at ( cx - 8 , 0 , cz - 8 ) . multiply ( 16 ) , BlockVector3 . at ( cx + 8 , 0 , cz + 8 ) . multiply ( 16 ) ) ;
2018-08-12 14:03:07 +00:00
}
2019-07-21 11:39:36 +00:00
int count = FaweAPI . fixLighting ( player . getWorld ( ) , selection , null ) ;
2019-11-21 19:56:10 +00:00
player . print ( TranslatableComponent . of ( " fawe.info.updated.lighting.selection " , count ) ) ;
2018-08-12 14:03:07 +00:00
}
@Command (
2019-07-06 00:46:48 +00:00
name = " /nbtinfo " ,
2019-10-23 04:23:52 +00:00
aliases = " /nbt " ,
2018-08-12 14:03:07 +00:00
desc = " View nbt info for a block "
)
@CommandPermissions ( " worldedit.nbtinfo " )
public void nbtinfo ( Player player , EditSession editSession ) {
Location pos = player . getBlockTrace ( 128 ) ;
if ( pos = = null ) {
2019-11-21 19:56:10 +00:00
player . printError ( TranslatableComponent . of ( " fawe.navigation.no.block " ) ) ;
2018-08-12 14:03:07 +00:00
return ;
}
2019-03-31 16:09:20 +00:00
CompoundTag nbt = editSession . getFullBlock ( pos . toBlockPoint ( ) ) . getNbtData ( ) ;
2018-08-12 14:03:07 +00:00
if ( nbt ! = null ) {
player . print ( nbt . getValue ( ) . toString ( ) ) ;
} else {
2019-11-21 19:56:10 +00:00
player . printError ( TranslatableComponent . of ( " fawe.navigation.no.block " ) ) ;
2018-08-12 14:03:07 +00:00
}
}
@Command (
2019-07-06 00:46:48 +00:00
name = " /setblocklight " ,
desc = " Set block lighting in a selection "
2018-08-12 14:03:07 +00:00
)
@CommandPermissions ( " worldedit.light.set " )
2019-11-20 00:11:54 +00:00
public void setlighting ( Player player , EditSession editSession , @Selection Region region , @Range ( from = 0 , to = 15 ) int value ) {
2019-07-21 11:39:36 +00:00
// TODO NOT IMPLEMENTED
2018-08-12 14:03:07 +00:00
}
@Command (
2019-07-17 05:43:18 +00:00
name = " /setskylight " ,
2019-07-06 00:46:48 +00:00
desc = " Set sky lighting in a selection "
2018-08-12 14:03:07 +00:00
)
@CommandPermissions ( " worldedit.light.set " )
2019-11-20 00:11:54 +00:00
public void setskylighting ( Player player , @Selection Region region , @Range ( from = 0 , to = 15 ) int value ) {
2019-07-21 11:39:36 +00:00
// TODO NOT IMPLEMENTED
2018-08-12 14:03:07 +00:00
}
@Command (
2019-07-06 00:46:48 +00:00
name = " /line " ,
desc = " Draws a line segment between cuboid selection corners " ,
descFooter = " Can only be used with a cuboid selection "
2014-04-03 02:08:50 +00:00
)
@CommandPermissions ( " worldedit.region.line " )
@Logging ( REGION )
2019-07-23 23:17:38 +00:00
public int line ( Actor actor , EditSession editSession ,
2019-07-06 00:46:48 +00:00
@Selection Region region ,
@Arg ( desc = " The pattern of blocks to place " )
2019-10-23 16:58:36 +00:00
Pattern pattern ,
2019-04-24 01:46:46 +00:00
@Arg ( desc = " The thickness of the line " , def = " 0 " )
2019-07-25 18:44:10 +00:00
int thickness ,
2019-07-06 00:46:48 +00:00
@Switch ( name = 'h' , desc = " Generate only a shell " )
boolean shell ) throws WorldEditException {
2014-04-03 02:08:50 +00:00
if ( ! ( region instanceof CuboidRegion ) ) {
2019-10-21 13:45:02 +00:00
actor . printError ( TranslatableComponent . of ( " worldedit.line.cuboid-only " ) ) ;
2019-07-06 00:46:48 +00:00
return 0 ;
2014-04-03 02:08:50 +00:00
}
2019-07-22 02:49:08 +00:00
checkCommandArgument ( thickness > = 0 , " Thickness must be >= 0 " ) ;
2014-04-03 02:08:50 +00:00
CuboidRegion cuboidregion = ( CuboidRegion ) region ;
2018-12-23 16:19:33 +00:00
BlockVector3 pos1 = cuboidregion . getPos1 ( ) ;
BlockVector3 pos2 = cuboidregion . getPos2 ( ) ;
2019-10-23 16:58:36 +00:00
int blocksChanged = editSession . drawLine ( pattern , pos1 , pos2 , thickness , ! shell ) ;
2014-04-03 02:08:50 +00:00
2019-10-27 05:29:40 +00:00
actor . printInfo ( TranslatableComponent . of ( " worldedit.line.changed " , TextComponent . of ( blocksChanged ) ) ) ;
2019-07-06 00:46:48 +00:00
return blocksChanged ;
2014-04-03 02:08:50 +00:00
}
@Command (
2019-07-06 00:46:48 +00:00
name = " /curve " ,
desc = " Draws a spline through selected points " ,
descFooter = " Can only be used with a convex polyhedral selection "
2014-04-03 02:08:50 +00:00
)
@CommandPermissions ( " worldedit.region.curve " )
@Logging ( REGION )
2019-11-21 06:50:37 +00:00
@Confirm ( Confirm . Processor . REGION )
2019-10-23 16:58:36 +00:00
public void curve ( Actor actor , EditSession editSession ,
2019-07-22 02:49:08 +00:00
@Selection Region region ,
@Arg ( desc = " The pattern of blocks to place " )
2019-10-23 16:58:36 +00:00
Pattern pattern ,
2019-07-22 02:49:08 +00:00
@Arg ( desc = " The thickness of the curve " , def = " 0 " )
2019-07-25 18:44:10 +00:00
int thickness ,
2019-07-22 02:49:08 +00:00
@Switch ( name = 'h' , desc = " Generate only a shell " )
2019-11-21 06:50:37 +00:00
boolean shell ) throws WorldEditException {
2014-04-03 02:08:50 +00:00
if ( ! ( region instanceof ConvexPolyhedralRegion ) ) {
2019-10-21 13:45:02 +00:00
actor . printError ( TranslatableComponent . of ( " worldedit.curve.convex-only " ) ) ;
2019-11-20 00:11:54 +00:00
return ;
2014-04-03 02:08:50 +00:00
}
2019-07-22 02:49:08 +00:00
checkCommandArgument ( thickness > = 0 , " Thickness must be >= 0 " ) ;
2018-08-12 14:03:07 +00:00
2018-12-23 16:19:33 +00:00
ConvexPolyhedralRegion cpregion = ( ConvexPolyhedralRegion ) region ;
List < BlockVector3 > vectors = new ArrayList < > ( cpregion . getVertices ( ) ) ;
2014-04-03 02:08:50 +00:00
2019-10-23 16:58:36 +00:00
int blocksChanged = editSession . drawSpline ( pattern , vectors , 0 , 0 , 0 , 10 , thickness , ! shell ) ;
2014-04-03 02:08:50 +00:00
2019-10-27 05:29:40 +00:00
actor . printInfo ( TranslatableComponent . of ( " worldedit.curve.changed " , TextComponent . of ( blocksChanged ) ) ) ;
2014-04-03 02:08:50 +00:00
}
@Command (
2019-07-06 00:46:48 +00:00
name = " /replace " ,
2019-12-11 22:46:47 +00:00
aliases = { " /re " , " /rep " } ,
2019-07-06 00:46:48 +00:00
desc = " Replace all blocks in the selection with another "
2014-04-03 02:08:50 +00:00
)
@CommandPermissions ( " worldedit.region.replace " )
@Logging ( REGION )
2019-11-21 06:50:37 +00:00
@Confirm ( Confirm . Processor . REGION )
2019-10-23 16:58:36 +00:00
public void replace ( Actor actor , EditSession editSession , @Selection Region region ,
2019-07-22 02:49:08 +00:00
@Arg ( desc = " The mask representing blocks to replace " , def = " " )
Mask from ,
@Arg ( desc = " The pattern of blocks to replace with " )
2019-11-21 06:50:37 +00:00
Pattern to ) throws WorldEditException {
2019-07-25 18:44:10 +00:00
if ( from = = null ) {
from = new ExistingBlockMask ( editSession ) ;
}
2018-06-15 05:41:37 +00:00
int affected = editSession . replaceBlocks ( region , from , to ) ;
2019-10-27 05:29:40 +00:00
actor . printInfo ( TranslatableComponent . of ( " worldedit.replace.replaced " , TextComponent . of ( affected ) ) ) ;
2018-08-12 14:03:07 +00:00
}
2014-04-03 02:08:50 +00:00
2018-08-12 14:03:07 +00:00
@Command (
2019-07-06 00:46:48 +00:00
name = " /overlay " ,
desc = " Set a block on top of blocks in the region "
2014-04-03 02:08:50 +00:00
)
@CommandPermissions ( " worldedit.region.overlay " )
@Logging ( REGION )
2019-11-21 06:50:37 +00:00
@Confirm ( Confirm . Processor . REGION )
2019-10-23 16:58:36 +00:00
public void overlay ( Actor actor , EditSession editSession , @Selection Region region ,
2019-07-22 02:49:08 +00:00
@Arg ( desc = " The pattern of blocks to overlay " )
2019-11-21 06:50:37 +00:00
Pattern pattern ) throws WorldEditException {
2018-06-15 05:41:37 +00:00
int affected = editSession . overlayCuboidBlocks ( region , pattern ) ;
2019-10-27 05:29:40 +00:00
actor . printInfo ( TranslatableComponent . of ( " worldedit.overlay.overlaid " , TextComponent . of ( affected ) ) ) ;
2014-04-03 02:08:50 +00:00
}
@Command (
2019-07-17 05:43:18 +00:00
name = " /lay " ,
desc = " Set the top block in the region "
)
2018-08-12 14:03:07 +00:00
@CommandPermissions ( " worldedit.region.overlay " )
@Logging ( REGION )
2019-11-21 06:50:37 +00:00
@Confirm ( Confirm . Processor . REGION )
public void lay ( Player player , EditSession editSession , @Selection Region region , @Arg ( name = " pattern " , desc = " The pattern of blocks to lay " ) Pattern patternArg ) throws WorldEditException {
BlockVector3 max = region . getMaximumPoint ( ) ;
int maxY = max . getBlockY ( ) ;
Iterable < BlockVector2 > flat = Regions . asFlatRegion ( region ) . asFlatRegion ( ) ;
Iterator < BlockVector2 > iter = flat . iterator ( ) ;
int y = 0 ;
int affected = 0 ;
while ( iter . hasNext ( ) ) {
BlockVector2 pos = iter . next ( ) ;
int x = pos . getBlockX ( ) ;
int z = pos . getBlockZ ( ) ;
y = editSession . getNearestSurfaceTerrainBlock ( x , z , y , 0 , maxY ) ;
editSession . setBlock ( x , y , z , patternArg ) ;
affected + + ;
}
2019-11-21 19:56:10 +00:00
player . print ( TranslatableComponent . of ( " fawe.worldedit.visitor.visitor.block " , affected ) ) ;
2018-08-12 14:03:07 +00:00
}
2019-07-22 02:49:08 +00:00
@Command (
2019-07-06 00:46:48 +00:00
name = " /center " ,
aliases = { " /middle " } ,
desc = " Set the center block(s) "
2014-04-03 02:08:50 +00:00
)
@Logging ( REGION )
@CommandPermissions ( " worldedit.region.center " )
2019-08-25 09:58:28 +00:00
public int center ( Actor actor , EditSession editSession , @Selection Region region ,
2019-07-22 02:49:08 +00:00
@Arg ( desc = " The pattern of blocks to set " )
2019-10-23 16:58:36 +00:00
Pattern pattern ) throws WorldEditException {
int affected = editSession . center ( region , pattern ) ;
2019-10-27 05:29:40 +00:00
actor . printInfo ( TranslatableComponent . of ( " worldedit.center.changed " , TextComponent . of ( affected ) ) ) ;
2019-04-24 01:46:46 +00:00
return affected ;
2014-04-03 02:08:50 +00:00
}
@Command (
2019-07-06 00:46:48 +00:00
name = " /naturalize " ,
desc = " 3 layers of dirt on top then rock below "
2014-04-03 02:08:50 +00:00
)
@CommandPermissions ( " worldedit.region.naturalize " )
@Logging ( REGION )
2019-11-21 06:50:37 +00:00
@Confirm ( Confirm . Processor . REGION )
public void naturalize ( Actor actor , EditSession editSession , @Selection Region region ) throws WorldEditException {
int affected = editSession . naturalizeCuboidBlocks ( region ) ;
2019-10-27 05:29:40 +00:00
actor . printInfo ( TranslatableComponent . of ( " worldedit.naturalize.naturalized " , TextComponent . of ( affected ) ) ) ;
2014-04-03 02:08:50 +00:00
}
@Command (
2019-07-06 00:46:48 +00:00
name = " /walls " ,
desc = " Build the four sides of the selection "
2014-04-03 02:08:50 +00:00
)
@CommandPermissions ( " worldedit.region.walls " )
@Logging ( REGION )
2019-11-21 06:50:37 +00:00
@Confirm ( Confirm . Processor . REGION )
2019-10-23 16:58:36 +00:00
public void walls ( Actor actor , EditSession editSession , @Selection Region region ,
2019-07-22 02:49:08 +00:00
@Arg ( desc = " The pattern of blocks to set " )
2019-11-21 06:50:37 +00:00
Pattern pattern ) throws WorldEditException {
int affected = editSession . makeWalls ( region , pattern ) ;
2019-10-27 05:29:40 +00:00
actor . printInfo ( TranslatableComponent . of ( " worldedit.walls.changed " , TextComponent . of ( affected ) ) ) ;
2014-04-03 02:08:50 +00:00
}
@Command (
2019-07-06 00:46:48 +00:00
name = " /faces " ,
aliases = { " /outline " } ,
desc = " Build the walls, ceiling, and floor of a selection "
2014-04-03 02:08:50 +00:00
)
@CommandPermissions ( " worldedit.region.faces " )
@Logging ( REGION )
2019-11-21 06:50:37 +00:00
@Confirm ( Confirm . Processor . REGION )
2019-10-23 16:58:36 +00:00
public void faces ( Actor actor , EditSession editSession , @Selection Region region ,
2019-07-22 02:49:08 +00:00
@Arg ( desc = " The pattern of blocks to set " )
2019-11-21 06:50:37 +00:00
Pattern pattern ) throws WorldEditException {
int affected = editSession . makeCuboidFaces ( region , pattern ) ;
2019-10-27 05:29:40 +00:00
actor . printInfo ( TranslatableComponent . of ( " worldedit.faces.changed " , TextComponent . of ( affected ) ) ) ;
2014-04-03 02:08:50 +00:00
}
@Command (
2019-07-06 00:46:48 +00:00
name = " /smooth " ,
2014-04-03 02:08:50 +00:00
desc = " Smooth the elevation in the selection " ,
2019-07-06 00:46:48 +00:00
descFooter = " Example: '//smooth 1 grass_block,dirt,stone' would only smooth natural surface terrain. "
2014-04-03 02:08:50 +00:00
)
2019-06-12 21:12:12 +00:00
@CommandPermissions ( " worldedit.region.smooth " )
2014-04-03 02:08:50 +00:00
@Logging ( REGION )
2019-11-21 06:50:37 +00:00
@Confirm ( Confirm . Processor . REGION )
2019-10-23 16:58:36 +00:00
public void smooth ( Actor actor , EditSession editSession , @Selection Region region ,
2019-07-22 02:49:08 +00:00
@Arg ( desc = " # of iterations to perform " , def = " 1 " )
int iterations ,
@Arg ( desc = " The mask of blocks to use as the height map " , def = " " )
2019-10-23 16:58:36 +00:00
Mask mask ,
2019-11-21 06:50:37 +00:00
@Switch ( name = 's' , desc = " TODO " ) boolean snow ) throws WorldEditException {
2019-07-22 20:42:40 +00:00
BlockVector3 min = region . getMinimumPoint ( ) ;
BlockVector3 max = region . getMaximumPoint ( ) ;
2018-09-07 15:31:30 +00:00
long volume = ( ( ( long ) max . getX ( ) - ( long ) min . getX ( ) + 1 ) * ( ( long ) max . getY ( ) - ( long ) min . getY ( ) + 1 ) * ( ( long ) max . getZ ( ) - ( long ) min . getZ ( ) + 1 ) ) ;
2019-10-23 16:58:36 +00:00
FaweLimit limit = actor . getLimit ( ) ;
2018-09-07 15:31:30 +00:00
if ( volume > = limit . MAX_CHECKS ) {
2019-10-23 14:35:04 +00:00
throw FaweCache . MAX_CHECKS ;
2018-09-07 15:31:30 +00:00
}
2019-11-21 06:50:37 +00:00
try {
HeightMap heightMap = new HeightMap ( editSession , region , mask , snow ) ;
2014-04-03 02:08:50 +00:00
HeightMapFilter filter = new HeightMapFilter ( new GaussianKernel ( 5 , 1 . 0 ) ) ;
int affected = heightMap . applyFilter ( filter , iterations ) ;
2019-10-27 05:29:40 +00:00
actor . printInfo ( TranslatableComponent . of ( " worldedit.smooth.changed " , TextComponent . of ( affected ) ) ) ;
2019-11-21 06:50:37 +00:00
} catch ( Throwable e ) {
throw new RuntimeException ( e ) ;
2019-11-21 13:50:05 +00:00
}
2018-08-12 14:03:07 +00:00
}
2014-04-03 02:08:50 +00:00
2018-08-12 14:03:07 +00:00
@Command (
2019-07-17 05:43:18 +00:00
name = " /wea " ,
aliases = { " wea " , " worldeditanywhere " , " /worldeditanywhere " , " /weanywhere " } ,
2018-08-12 14:03:07 +00:00
desc = " Bypass region restrictions " ,
2019-07-17 05:43:18 +00:00
descFooter = " Bypass region restrictions "
2018-08-12 14:03:07 +00:00
)
@CommandPermissions ( " fawe.admin " )
2019-10-23 16:58:36 +00:00
public void wea ( Actor actor ) throws WorldEditException {
if ( actor . togglePermission ( " fawe.bypass " ) ) {
2019-11-21 19:56:10 +00:00
actor . print ( TranslatableComponent . of ( " fawe.info.worldedit.bypassed " ) ) ;
2018-08-12 14:03:07 +00:00
} else {
2019-11-21 19:56:10 +00:00
actor . print ( TranslatableComponent . of ( " fawe.info.worldedit.restricted " ) ) ;
2018-08-12 14:03:07 +00:00
}
2014-04-03 02:08:50 +00:00
}
@Command (
2019-07-17 05:43:18 +00:00
name = " /wer " ,
aliases = { " wer " , " worldeditregion " , " /worldeditregion " , " select " , " /select " } ,
2018-08-12 14:03:07 +00:00
desc = " Select your current allowed region " ,
2019-07-17 05:43:18 +00:00
descFooter = " Select your current allowed region "
2018-08-12 14:03:07 +00:00
)
@CommandPermissions ( " fawe.worldeditregion " )
2019-10-23 16:58:36 +00:00
public void wer ( Player player ) throws WorldEditException {
final Region region = player . getLargestRegion ( ) ;
2018-08-12 14:03:07 +00:00
if ( region = = null ) {
2019-11-21 19:56:10 +00:00
player . print ( TranslatableComponent . of ( " fawe.error.no.region " ) ) ;
2018-08-12 14:03:07 +00:00
} else {
2019-10-23 16:58:36 +00:00
player . setSelection ( region ) ;
2019-11-21 19:56:10 +00:00
player . print ( TranslatableComponent . of ( " fawe.info.set.region " ) ) ;
2018-08-12 14:03:07 +00:00
}
}
@Command (
2019-07-17 05:43:18 +00:00
name = " /move " ,
2019-10-30 11:26:52 +00:00
aliases = { " /mv " } ,
2019-07-23 23:17:38 +00:00
desc = " Move the contents of the selection "
)
2014-04-03 02:08:50 +00:00
@CommandPermissions ( " worldedit.region.move " )
@Logging ( ORIENTATION_REGION )
2019-11-21 06:50:37 +00:00
@Confirm ( Confirm . Processor . REGION )
2019-11-21 19:56:10 +00:00
public int move ( Actor actor , World world , EditSession editSession , LocalSession session ,
2019-11-20 00:11:54 +00:00
@Selection Region region ,
2019-07-22 02:49:08 +00:00
@Arg ( desc = " # of blocks to move " , def = " 1 " )
2019-11-20 00:11:54 +00:00
int count ,
2019-07-22 02:49:08 +00:00
@Arg ( desc = " The direction to move " , def = Direction . AIM )
@Direction ( includeDiagonals = true )
2019-11-20 00:11:54 +00:00
BlockVector3 direction ,
2019-07-22 02:49:08 +00:00
@Arg ( desc = " The pattern of blocks to leave " , def = " air " )
2019-11-20 00:11:54 +00:00
Pattern replace ,
2019-07-22 02:49:08 +00:00
@Switch ( name = 's' , desc = " Shift the selection to the target location " )
2019-11-20 00:11:54 +00:00
boolean moveSelection ,
2019-07-22 02:49:08 +00:00
@Switch ( name = 'a' , desc = " Ignore air blocks " )
2019-11-20 00:11:54 +00:00
boolean ignoreAirBlocks ,
@Switch ( name = 'e' , desc = " Skip copy entities " )
boolean skipEntities ,
2019-10-23 18:29:37 +00:00
@Switch ( name = 'b' , desc = " Also copy biomes " )
2019-11-20 00:11:54 +00:00
boolean copyBiomes ,
@ArgFlag ( name = 'm' , desc = " Set the include mask, non-matching blocks become air " , def = " " )
2019-11-21 06:50:37 +00:00
Mask mask ) throws WorldEditException {
2019-07-22 02:49:08 +00:00
checkCommandArgument ( count > = 1 , " Count must be >= 1 " ) ;
2019-12-11 22:46:47 +00:00
2019-11-19 21:23:47 +00:00
Mask combinedMask ;
2019-08-03 16:59:24 +00:00
if ( ignoreAirBlocks ) {
if ( mask = = null ) {
combinedMask = new ExistingBlockMask ( editSession ) ;
} else {
combinedMask = new MaskIntersection ( mask , new ExistingBlockMask ( editSession ) ) ;
}
} else {
combinedMask = mask ;
}
2019-12-11 22:46:47 +00:00
2019-11-21 06:50:37 +00:00
int affected = editSession . moveRegion ( region , direction , count , ! skipEntities , copyBiomes , combinedMask , replace ) ;
if ( moveSelection ) {
try {
region . shift ( direction . multiply ( count ) ) ;
session . getRegionSelector ( world ) . learnChanges ( ) ;
session . getRegionSelector ( world ) . explainRegionAdjust ( actor , session ) ;
} catch ( RegionOperationException e ) {
2019-10-21 13:45:02 +00:00
actor . printError ( TextComponent . of ( e . getMessage ( ) ) ) ;
2014-04-03 02:08:50 +00:00
}
2019-11-21 06:50:37 +00:00
}
2014-04-03 02:08:50 +00:00
2019-10-27 05:29:40 +00:00
actor . printInfo ( TranslatableComponent . of ( " worldedit.move.moved " , TextComponent . of ( affected ) ) ) ;
2019-04-24 01:46:46 +00:00
return affected ;
2014-04-03 02:08:50 +00:00
}
@Command (
2019-07-17 05:43:18 +00:00
name = " /fall " ,
2018-08-12 14:03:07 +00:00
desc = " Have the blocks in the selection fall " ,
2019-07-17 05:43:18 +00:00
descFooter = " Make the blocks in the selection fall \ n " +
" The -m flag will only fall within the vertical selection. "
)
2018-08-12 14:03:07 +00:00
@CommandPermissions ( " worldedit.region.fall " )
@Logging ( ORIENTATION_REGION )
2019-11-21 06:50:37 +00:00
@Confirm ( Confirm . Processor . REGION )
2019-09-14 03:05:16 +00:00
public void fall ( Player player , EditSession editSession , LocalSession session ,
2018-08-12 14:03:07 +00:00
@Selection Region region ,
2019-10-23 16:58:36 +00:00
@Arg ( desc = " BlockStateHolder " , def = " air " ) BlockStateHolder replace ,
2019-11-21 06:50:37 +00:00
@Switch ( name = 'm' , desc = " TODO " ) boolean notFullHeight ) throws WorldEditException {
int affected = editSession . fall ( region , ! notFullHeight , replace ) ;
2019-11-21 19:56:10 +00:00
player . print ( TranslatableComponent . of ( " fawe.worldedit.visitor.visitor.block " , affected ) ) ;
2018-08-12 14:03:07 +00:00
}
@Command (
2019-07-06 00:46:48 +00:00
name = " /stack " ,
desc = " Repeat the contents of the selection "
2014-04-03 02:08:50 +00:00
)
@CommandPermissions ( " worldedit.region.stack " )
@Logging ( ORIENTATION_REGION )
2019-11-21 19:56:10 +00:00
public int stack ( Actor actor , World world , EditSession editSession , LocalSession session ,
2019-07-22 02:49:08 +00:00
@Selection Region region ,
@Arg ( desc = " # of copies to stack " , def = " 1 " )
2019-12-11 22:46:47 +00:00
@Confirm ( Confirm . Processor . REGION )
int count ,
2019-07-22 02:49:08 +00:00
@Arg ( desc = " The direction to stack " , def = Direction . AIM )
@Direction ( includeDiagonals = true )
BlockVector3 direction ,
@Switch ( name = 's' , desc = " Shift the selection to the last stacked copy " )
boolean moveSelection ,
@Switch ( name = 'a' , desc = " Ignore air blocks " )
boolean ignoreAirBlocks ,
2019-10-23 18:29:37 +00:00
@Switch ( name = 'e' , desc = " Skip entities " )
boolean skipEntities ,
@Switch ( name = 'b' , desc = " Also copy biomes " )
boolean copyBiomes ,
2019-11-23 05:33:46 +00:00
@ArgFlag ( name = 'm' , desc = " Set the include mask, non-matching blocks become air " , def = " " )
2019-11-21 06:50:37 +00:00
Mask mask ) throws WorldEditException {
2019-12-11 22:46:47 +00:00
2019-11-19 21:23:47 +00:00
Mask combinedMask ;
2019-08-03 16:59:24 +00:00
if ( ignoreAirBlocks ) {
if ( mask = = null ) {
combinedMask = new ExistingBlockMask ( editSession ) ;
} else {
combinedMask = new MaskIntersection ( mask , new ExistingBlockMask ( editSession ) ) ;
}
} else {
combinedMask = mask ;
}
2019-12-11 22:46:47 +00:00
2019-11-21 06:50:37 +00:00
int affected = editSession . stackCuboidRegion ( region , direction , count , ! skipEntities , copyBiomes , combinedMask ) ;
2018-09-07 15:09:31 +00:00
2019-11-21 06:50:37 +00:00
if ( moveSelection ) {
try {
final BlockVector3 size = region . getMaximumPoint ( ) . subtract ( region . getMinimumPoint ( ) ) . add ( 1 , 1 , 1 ) ;
2019-07-23 23:17:38 +00:00
2019-11-21 06:50:37 +00:00
final BlockVector3 shiftVector = direction . multiply ( size ) . multiply ( count ) ;
region . shift ( shiftVector ) ;
2018-09-07 15:09:31 +00:00
2019-11-21 06:50:37 +00:00
session . getRegionSelector ( world ) . learnChanges ( ) ;
session . getRegionSelector ( world ) . explainRegionAdjust ( actor , session ) ;
} catch ( RegionOperationException e ) {
2019-10-21 13:45:02 +00:00
actor . printError ( TextComponent . of ( e . getMessage ( ) ) ) ;
2014-04-03 02:08:50 +00:00
}
2019-11-21 06:50:37 +00:00
}
2014-04-03 02:08:50 +00:00
2019-10-27 05:29:40 +00:00
actor . printInfo ( TranslatableComponent . of ( " worldedit.stack.changed " , TextComponent . of ( affected ) ) ) ;
2019-04-24 01:46:46 +00:00
return affected ;
2014-04-03 02:08:50 +00:00
}
2019-12-11 22:46:47 +00:00
@Command (
name = " /regen " ,
desc = " Regenerates the contents of the selection " ,
descFooter = " This command might affect things outside the selection, \ n " +
" if they are within the same chunk. "
)
@CommandPermissions ( " worldedit.regen " )
@Logging ( REGION )
@Confirm ( Confirm . Processor . REGION )
public void regenerateChunk ( Actor actor , World world , LocalSession session ,
EditSession editSession , @Selection Region region ,
@Arg ( def = " " , desc = " Regenerate with biome " ) BiomeType biome ,
@Arg ( def = " " , desc = " Regenerate with seed " ) Long seed ) throws WorldEditException {
Mask mask = session . getMask ( ) ;
session . setMask ( ( Mask ) null ) ;
session . setSourceMask ( ( Mask ) null ) ;
world . regenerate ( region , editSession ) ;
// editSession.regenerate(region, biome, seed);
session . setMask ( mask ) ;
session . setSourceMask ( mask ) ;
actor . printInfo ( TranslatableComponent . of ( " worldedit.regen.regenerated " ) ) ;
}
2014-04-03 02:08:50 +00:00
@Command (
2019-07-22 02:49:08 +00:00
name = " /deform " ,
desc = " Deforms a selected region with an expression " ,
descFooter = " The expression is executed for each block and is expected \ n " +
" to modify the variables x, y and z to point to a new block \ n " +
" to fetch. See also https://tinyurl.com/weexpr "
)
2014-04-03 02:08:50 +00:00
@CommandPermissions ( " worldedit.region.deform " )
@Logging ( ALL )
2019-11-21 06:50:37 +00:00
@Confirm ( Confirm . Processor . REGION )
public void deform ( Actor actor , LocalSession session , EditSession editSession ,
2019-07-22 02:49:08 +00:00
@Selection Region region ,
@Arg ( desc = " The expression to use " , variable = true )
List < String > expression ,
@Switch ( name = 'r' , desc = " Use the game's coordinate origin " )
boolean useRawCoords ,
@Switch ( name = 'o' , desc = " Use the selection's center as origin " )
boolean offset ) throws WorldEditException {
2018-12-23 16:19:33 +00:00
final Vector3 zero ;
Vector3 unit ;
2019-06-12 21:12:12 +00:00
2018-09-07 15:31:30 +00:00
if ( useRawCoords ) {
2018-12-23 16:19:33 +00:00
zero = Vector3 . ZERO ;
unit = Vector3 . ONE ;
2018-09-07 15:31:30 +00:00
} else if ( offset ) {
2019-10-23 16:58:36 +00:00
zero = session . getPlacementPosition ( actor ) . toVector3 ( ) ;
2018-12-23 16:19:33 +00:00
unit = Vector3 . ONE ;
2018-09-07 15:31:30 +00:00
} else {
2018-12-23 16:19:33 +00:00
final Vector3 min = region . getMinimumPoint ( ) . toVector3 ( ) ;
final Vector3 max = region . getMaximumPoint ( ) . toVector3 ( ) ;
2014-04-03 02:08:50 +00:00
2018-12-23 16:19:33 +00:00
zero = max . add ( min ) . divide ( 2 ) ;
2018-09-07 15:31:30 +00:00
unit = max . subtract ( zero ) ;
2018-12-23 16:19:33 +00:00
if ( unit . getX ( ) = = 0 ) unit = unit . withX ( 1 . 0 ) ;
if ( unit . getY ( ) = = 0 ) unit = unit . withY ( 1 . 0 ) ;
if ( unit . getZ ( ) = = 0 ) unit = unit . withZ ( 1 . 0 ) ;
2018-09-07 15:31:30 +00:00
}
2019-06-06 01:17:34 +00:00
2019-01-09 07:13:44 +00:00
final Vector3 unit1 = unit ;
2019-11-21 06:50:37 +00:00
try {
final int affected = editSession . deformRegion ( region , zero , unit1 , String . join ( " " , expression ) , session . getTimeout ( ) ) ;
if ( actor instanceof Player ) {
( ( Player ) actor ) . findFreePosition ( ) ;
2018-09-07 15:09:31 +00:00
}
2019-10-27 05:29:40 +00:00
actor . printInfo ( TranslatableComponent . of ( " worldedit.deform.deformed " , TextComponent . of ( affected ) ) ) ;
2019-11-21 06:50:37 +00:00
} catch ( ExpressionException e ) {
2019-10-21 13:45:02 +00:00
actor . printError ( TextComponent . of ( e . getMessage ( ) ) ) ;
2019-11-21 06:50:37 +00:00
}
2018-08-12 14:03:07 +00:00
}
2014-04-03 02:08:50 +00:00
@Command (
2019-07-22 02:49:08 +00:00
name = " /hollow " ,
2019-06-12 21:12:12 +00:00
desc = " Hollows out the object contained in this selection " ,
2019-07-17 05:43:18 +00:00
descFooter = " Hollows out the object contained in this selection. \ n " +
2019-06-12 21:12:12 +00:00
" Optionally fills the hollowed out part with the given block. \ n " +
2019-07-17 05:43:18 +00:00
" Thickness is measured in manhattan distance. "
2019-07-18 06:56:57 +00:00
2014-04-03 02:08:50 +00:00
)
@CommandPermissions ( " worldedit.region.hollow " )
@Logging ( REGION )
2019-11-21 06:50:37 +00:00
@Confirm ( Confirm . Processor . REGION )
2019-10-23 16:58:36 +00:00
public void hollow ( Actor actor , EditSession editSession ,
2019-07-22 02:49:08 +00:00
@Selection Region region ,
2019-11-20 00:11:54 +00:00
@Range ( from = 0 , to = Integer . MAX_VALUE ) @Arg ( desc = " Thickness of the shell to leave " , def = " 0 " )
2019-07-23 23:17:38 +00:00
int thickness ,
2019-10-23 16:58:36 +00:00
@Arg ( desc = " The pattern of blocks to replace the hollowed area with " , def = " air " )
Pattern pattern ,
2019-11-21 06:50:37 +00:00
@ArgFlag ( name = 'm' , desc = " Mask to hollow with " ) Mask mask ) throws WorldEditException {
2019-07-23 23:17:38 +00:00
checkCommandArgument ( thickness > = 0 , " Thickness must be >= 0 " ) ;
2019-07-18 06:56:57 +00:00
Mask finalMask = mask = = null ? new SolidBlockMask ( editSession ) : mask ;
2019-11-21 06:50:37 +00:00
int affected = editSession . hollowOutRegion ( region , thickness , pattern , finalMask ) ;
2019-10-27 05:29:40 +00:00
actor . printInfo ( TranslatableComponent . of ( " worldedit.hollow.changed " , TextComponent . of ( affected ) ) ) ;
2014-04-03 02:08:50 +00:00
}
@Command (
2019-07-06 00:46:48 +00:00
name = " /forest " ,
desc = " Make a forest within the region "
2014-04-03 02:08:50 +00:00
)
@CommandPermissions ( " worldedit.region.forest " )
@Logging ( REGION )
2019-11-21 06:50:37 +00:00
@Confirm ( Confirm . Processor . REGION )
2019-07-23 23:17:38 +00:00
public int forest ( Actor actor , EditSession editSession , @Selection Region region ,
2019-07-22 02:49:08 +00:00
@Arg ( desc = " The type of tree to place " , def = " tree " )
TreeType type ,
@Arg ( desc = " The density of the forest " , def = " 5 " )
double density ) throws WorldEditException {
checkCommandArgument ( 0 < = density & & density < = 100 , " Density must be in [0, 100] " ) ;
2019-03-21 01:05:11 +00:00
int affected = editSession . makeForest ( region , density / 100 , type ) ;
2019-10-27 05:29:40 +00:00
actor . printInfo ( TranslatableComponent . of ( " worldedit.forest.created " , TextComponent . of ( affected ) ) ) ;
2019-07-23 23:17:38 +00:00
return affected ;
2014-04-03 02:08:50 +00:00
}
@Command (
2019-07-06 00:46:48 +00:00
name = " /flora " ,
desc = " Make flora within the region "
2014-04-03 02:08:50 +00:00
)
@CommandPermissions ( " worldedit.region.flora " )
@Logging ( REGION )
2019-11-21 06:50:37 +00:00
@Confirm ( Confirm . Processor . REGION )
2019-10-23 16:58:36 +00:00
public void flora ( Actor actor , EditSession editSession , @Selection Region region ,
2019-07-22 02:49:08 +00:00
@Arg ( desc = " The density of the forest " , def = " 5 " )
2019-11-21 06:50:37 +00:00
double density ) throws WorldEditException {
2019-07-22 02:49:08 +00:00
checkCommandArgument ( 0 < = density & & density < = 100 , " Density must be in [0, 100] " ) ;
2019-11-21 06:50:37 +00:00
FloraGenerator generator = new FloraGenerator ( editSession ) ;
GroundFunction ground = new GroundFunction ( new ExistingBlockMask ( editSession ) , generator ) ;
LayerVisitor visitor = new LayerVisitor ( asFlatRegion ( region ) , minimumBlockY ( region ) , maximumBlockY ( region ) , ground ) ;
visitor . setMask ( new NoiseFilter2D ( new RandomNoise ( ) , density / 100 ) ) ;
Operations . completeLegacy ( visitor ) ;
int affected = ground . getAffected ( ) ;
2019-10-27 05:29:40 +00:00
actor . printInfo ( TranslatableComponent . of ( " worldedit.flora.created " , TextComponent . of ( affected ) ) ) ;
2014-04-03 02:08:50 +00:00
}
2019-04-02 20:26:51 +00:00
}