From e4709eb6dc940fc6b333a2a35db11510407a85c6 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Wed, 16 Dec 2020 12:34:54 +0000 Subject: [PATCH 1/6] idk why I did &3 half fixes #769 --- .../boydti/fawe/beta/implementation/blocks/CharSetBlocks.java | 4 ++-- .../src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java index 85ba848a6..771c955d2 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java @@ -57,7 +57,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet { if (biomes == null) { return null; } - return biomes[(y >> 2) << 4 | (z & 3) << 2 | x & 3]; + return biomes[(y >> 2) << 4 | (z >> 2) << 2 | x >> 2]; } @Override @@ -90,7 +90,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet { if (biomes == null) { biomes = new BiomeType[1024]; } - biomes[(y >> 2) << 4 | (z & 3) << 2 | x & 3] = biome; + biomes[(y >> 2) << 4 | (z >> 2) << 2 | x >> 2] = biome; return true; } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java b/worldedit-core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java index a4150f274..07b99a456 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java @@ -481,7 +481,7 @@ public class MCAChunk implements IChunk { @Override public BiomeType getBiomeType(int x, int y, int z) { - return this.biomes[(y >> 2) << 4 | (z & 3) << 2 | x & 3]; + return this.biomes[(y >> 2) << 4 | (z >> 2) << 2 | x >> 2]; } @Override @@ -505,7 +505,7 @@ public class MCAChunk implements IChunk { @Override public boolean setBiome(int x, int y, int z, BiomeType biome) { setModified(); - biomes[(y >> 2) << 4 | (z & 3) << 2 | x & 3] = biome; + biomes[(y >> 2) << 4 | (z >> 2) << 2 | x >> 2] = biome; return true; } From 3a3bf7382daa93cbd2aa6cb5ac7aaf7a787897cf Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Wed, 16 Dec 2020 16:59:16 +0000 Subject: [PATCH 2/6] Update block NBT to include the coordinates when saving to history fixes #708 and fixes #655 --- .../com/boydti/fawe/object/changeset/AbstractChangeSet.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractChangeSet.java b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractChangeSet.java index c41457655..dad021ee1 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractChangeSet.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractChangeSet.java @@ -137,7 +137,10 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor { } if (!tilesTo.isEmpty()) { for (Map.Entry entry : tilesTo.entrySet()) { - addTileCreate(entry.getValue()); + CompoundTag nbt = entry.getValue(); + BlockVector3 pos = entry.getKey(); + MainUtil.setPosition(nbt, pos.getX() + bx, pos.getY(), pos.getZ() + bz); + addTileCreate(nbt); } } Set entRemoves = set.getEntityRemoves(); From 61fd8c0de5cad7d714b96e712960c5a924459a49 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Wed, 16 Dec 2020 17:20:33 +0000 Subject: [PATCH 3/6] Update generate tree to match upstream --- .../src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index f282901c1..b5a947b13 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -301,6 +301,9 @@ public class BukkitWorld extends AbstractWorld { public boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, BlockVector3 pt) { World world = getWorld(); TreeType bukkitType = toBukkitTreeType(type); + if (bukkitType == TreeType.CHORUS_PLANT) { + pt = pt.add(0, 1, 0); // bukkit skips the feature gen which does this offset normally, so we have to add it back + } return type != null && world.generateTree(BukkitAdapter.adapt(world, pt), bukkitType, new EditSessionBlockChangeDelegate(editSession)); } From aeccce24a916e0b433c61881b34ab2a6fbbb1f3d Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Wed, 16 Dec 2020 17:38:15 +0000 Subject: [PATCH 4/6] fix #550 --- .../com/boydti/fawe/wrappers/AsyncPlayer.java | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/wrappers/AsyncPlayer.java b/worldedit-core/src/main/java/com/boydti/fawe/wrappers/AsyncPlayer.java index baca0fa1f..1001d64bd 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/wrappers/AsyncPlayer.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/wrappers/AsyncPlayer.java @@ -143,23 +143,27 @@ public class AsyncPlayer extends PlayerProxy { @Override public void floatAt(int x, int y, int z, boolean alwaysGlass) { - RuntimeException caught = null; - try { - EditSession edit = new EditSessionBuilder(WorldWrapper.unwrap(getWorld())) - .player(unwrap(getBasePlayer())).build(); - edit.setBlock(BlockVector3.at(x, y - 1, z), BlockTypes.GLASS); - edit.flushQueue(); - LocalSession session = Fawe.get().getWorldEdit().getSessionManager().get(this); - if (session != null) { - session.remember(edit, true, getBasePlayer().getLimit().MAX_HISTORY); + if (alwaysGlass || !isAllowedToFly()) { + RuntimeException caught = null; + try { + EditSession edit = + new EditSessionBuilder(WorldWrapper.unwrap(getWorld())).player(unwrap(getBasePlayer())).build(); + edit.setBlock(BlockVector3.at(x, y - 1, z), BlockTypes.GLASS); + edit.flushQueue(); + LocalSession session = Fawe.get().getWorldEdit().getSessionManager().get(this); + if (session != null) { + session.remember(edit, true, getBasePlayer().getLimit().MAX_HISTORY); + } + } catch (RuntimeException e) { + caught = e; } - } catch (RuntimeException e) { - caught = e; - } - setPosition(Vector3.at(x + 0.5, y, z + 0.5)); - if (caught != null) { - throw caught; + if (caught != null) { + throw caught; + } + } else { + setFlying(true); } + trySetPosition(Vector3.at(x + 0.5, y, z + 0.5)); } @Override From d5005a04e3c1f14505117f1173cdb1c43123f3fa Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Wed, 16 Dec 2020 19:08:00 +0000 Subject: [PATCH 5/6] Return air if attempt to retrieve block from outside range Fixes #682 --- .../com/boydti/fawe/beta/implementation/blocks/CharBlocks.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java index c62207a1a..52ddbb1e7 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java @@ -115,6 +115,9 @@ public abstract class CharBlocks implements IBlocks { public char get(int x, @Range(from = 0, to = 255) int y, int z) { final int layer = y >> 4; final int index = (y & 15) << 8 | z << 4 | x; + if (layer >= sections.length || layer < 0) { + return 0; + } return sections[layer].get(this, layer, index); } From f347e0f5f59e7ac9a3444adecc5b4f42596fc8a5 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Wed, 16 Dec 2020 19:23:41 +0000 Subject: [PATCH 6/6] update some utility commands fixes #557 --- .../java/com/sk89q/worldedit/EditSession.java | 200 ++++++++++-------- .../worldedit/command/UtilityCommands.java | 60 +++++- .../function/block/SnowSimulator.java | 18 +- 3 files changed, 178 insertions(+), 100 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index 846bc0794..e6051f754 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -57,6 +57,7 @@ import com.sk89q.worldedit.function.GroundFunction; import com.sk89q.worldedit.function.RegionFunction; import com.sk89q.worldedit.function.block.BlockReplace; import com.sk89q.worldedit.function.block.Naturalizer; +import com.sk89q.worldedit.function.block.SnowSimulator; import com.sk89q.worldedit.function.generator.ForestGenerator; import com.sk89q.worldedit.function.generator.GardenPatchGenerator; import com.sk89q.worldedit.function.mask.BlockStateMask; @@ -97,6 +98,7 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.MathUtils; import com.sk89q.worldedit.math.MutableBlockVector2; import com.sk89q.worldedit.math.MutableBlockVector3; +import com.sk89q.worldedit.math.Vector2; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.interpolation.Interpolation; import com.sk89q.worldedit.math.interpolation.KochanekBartelsInterpolation; @@ -104,6 +106,7 @@ import com.sk89q.worldedit.math.interpolation.Node; import com.sk89q.worldedit.math.noise.RandomNoise; import com.sk89q.worldedit.math.transform.AffineTransform; import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.CylinderRegion; import com.sk89q.worldedit.regions.EllipsoidRegion; import com.sk89q.worldedit.regions.FlatRegion; import com.sk89q.worldedit.regions.Region; @@ -148,6 +151,7 @@ import java.util.UUID; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import static com.sk89q.worldedit.function.block.SnowSimulator.snowy; import static com.sk89q.worldedit.regions.Regions.asFlatRegion; import static com.sk89q.worldedit.regions.Regions.maximumBlockY; import static com.sk89q.worldedit.regions.Regions.minimumBlockY; @@ -2150,9 +2154,25 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { * @param radius the radius * @return number of blocks affected * @throws MaxChangedBlocksException thrown if too many blocks are changed + * @deprecated Use {@link #thaw(BlockVector3, double, int)}. */ @Deprecated public int thaw(BlockVector3 position, double radius) + throws MaxChangedBlocksException { + return thaw(position, radius, + WorldEdit.getInstance().getConfiguration().defaultVerticalHeight); + } + + /** + * Thaw blocks in a cylinder. + * + * @param position the position + * @param radius the radius + * @param height the height (upwards and downwards) + * @return number of blocks affected + * @throws MaxChangedBlocksException thrown if too many blocks are changed + */ + public int thaw(BlockVector3 position, double radius, int height) throws MaxChangedBlocksException { int affected = 0; double radiusSq = radius * radius; @@ -2164,6 +2184,10 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { BlockState air = BlockTypes.AIR.getDefaultState(); BlockState water = BlockTypes.WATER.getDefaultState(); + int centerY = Math.max(getWorld().getMinY(), Math.min(getWorld().getMaxY(), oy)); + int minY = Math.max(getWorld().getMinY(), centerY - height); + int maxY = Math.min(getWorld().getMaxY(), centerY + height); + int ceilRadius = (int) Math.ceil(radius); for (int x = ox - ceilRadius; x <= ox + ceilRadius; ++x) { for (int z = oz - ceilRadius; z <= oz + ceilRadius; ++z) { @@ -2171,15 +2195,25 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { continue; } - for (int y = maxY; y >= 1; --y) { - BlockType id = getBlock(x, y, z).getBlockType(); + for (int y = maxY; y > minY; --y) { + BlockVector3 pt = BlockVector3.at(x, y, z); + BlockVector3 below = BlockVector3.at(x, y - 1, z); + BlockType id = getBlock(pt).getBlockType(); if (id == BlockTypes.ICE) { - if (setBlock(x, y, z, water)) { + if (setBlock(pt, water)) { ++affected; } } else if (id == BlockTypes.SNOW) { - if (setBlock(x, y, z, air)) { + if (setBlock(pt, air)) { + if (y > 0 ) { + BlockState block = getBlock(below); + if (block.getStates().containsKey(snowy)) { + if (setBlock(below, block.with(snowy, false))) { + affected++; + } + } + } ++affected; } } else if (id.getMaterial().isAir()) { @@ -2191,7 +2225,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { } } - return changes = affected; + return affected; } /** @@ -2201,67 +2235,46 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { * @param radius a radius * @return number of blocks affected * @throws MaxChangedBlocksException thrown if too many blocks are changed + * @deprecated Use {@link #simulateSnow(BlockVector3, double, int)}. */ @Deprecated public int simulateSnow(BlockVector3 position, double radius) throws MaxChangedBlocksException { - int affected = 0; - double radiusSq = radius * radius; - - int ox = position.getBlockX(); - int oy = position.getBlockY(); - int oz = position.getBlockZ(); - - BlockState ice = BlockTypes.ICE.getDefaultState(); - BlockState snow = BlockTypes.SNOW.getDefaultState(); - - int ceilRadius = (int) Math.ceil(radius); - for (int x = ox - ceilRadius; x <= ox + ceilRadius; ++x) { - for (int z = oz - ceilRadius; z <= oz + ceilRadius; ++z) { - if ((BlockVector3.at(x, oy, z)).distanceSq(position) > radiusSq) { - continue; - } - - for (int y = maxY; y >= 1; --y) { - BlockVector3 pt = BlockVector3.at(x, y, z); - BlockType id = getBlock(pt).getBlockType(); - - if (id.getMaterial().isAir()) { - continue; - } - - // Ice! - if (id == BlockTypes.WATER) { - if (setBlock(pt, ice)) { - ++affected; - } - break; - } - - // Snow should not cover these blocks - if (id.getMaterial().isTranslucent()) { - // Add snow on leaves - if (!BlockCategories.LEAVES.contains(id)) { - break; - } - } - - // Too high? - if (y == maxY) { - break; - } - - // add snow cover - if (setBlock(pt.add(0, 1, 0), snow)) { - ++affected; - } - break; - } - } - } - - return changes = affected; + return simulateSnow(position, radius, + WorldEdit.getInstance().getConfiguration().defaultVerticalHeight); } + /** + * Make snow in a cylinder. + * + * @param position a position + * @param radius a radius + * @param height the height (upwards and downwards) + * @return number of blocks affected + * @throws MaxChangedBlocksException thrown if too many blocks are changed + */ + public int simulateSnow(BlockVector3 position, double radius, int height) + throws MaxChangedBlocksException { + + return simulateSnow(new CylinderRegion(position, Vector2.at(radius, radius), position.getBlockY(), height), false); + } + + /** + * Make snow in a region. + * + * @param region the region to simulate snow in + * @param stack whether it should stack existing snow + * @return number of blocks affected + * @throws MaxChangedBlocksException thrown if too many blocks are changed + */ + public int simulateSnow(FlatRegion region, boolean stack) + throws MaxChangedBlocksException { + checkNotNull(region); + + SnowSimulator snowSimulator = new SnowSimulator(this, stack); + LayerVisitor layerVisitor = new LayerVisitor(region, region.getMinimumY(), region.getMaximumY(), snowSimulator); + Operations.completeLegacy(layerVisitor); + return snowSimulator.getAffected(); + } /** * Make dirt green. * @@ -2270,52 +2283,67 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { * @param onlyNormalDirt only affect normal dirt (all default properties) * @return number of blocks affected * @throws MaxChangedBlocksException thrown if too many blocks are changed + * @deprecated Use {@link #green(BlockVector3, double, int, boolean)}. */ @Deprecated public int green(BlockVector3 position, double radius, boolean onlyNormalDirt) throws MaxChangedBlocksException { + return green(position, radius, + WorldEdit.getInstance().getConfiguration().defaultVerticalHeight, onlyNormalDirt); + } + + /** + * Make dirt green in a cylinder. + * + * @param position the position + * @param radius the radius + * @param height the height + * @param onlyNormalDirt only affect normal dirt (all default properties) + * @return number of blocks affected + * @throws MaxChangedBlocksException thrown if too many blocks are changed + */ + public int green(BlockVector3 position, double radius, int height, boolean onlyNormalDirt) + throws MaxChangedBlocksException { + int affected = 0; final double radiusSq = radius * radius; final int ox = position.getBlockX(); + final int oy = position.getBlockY(); final int oz = position.getBlockZ(); final BlockState grass = BlockTypes.GRASS_BLOCK.getDefaultState(); + final int centerY = Math.max(getWorld().getMinY(), Math.min(getWorld().getMaxY(), oy)); + final int minY = Math.max(getWorld().getMinY(), centerY - height); + final int maxY = Math.min(getWorld().getMaxY(), centerY + height); + final int ceilRadius = (int) Math.ceil(radius); for (int x = ox - ceilRadius; x <= ox + ceilRadius; ++x) { - int dx = x - ox; - int dx2 = dx * dx; for (int z = oz - ceilRadius; z <= oz + ceilRadius; ++z) { - int dz = z - oz; - int dz2 = dz * dz; - if (dx2 + dz2 > radiusSq) { + if ((BlockVector3.at(x, oy, z)).distanceSq(position) > radiusSq) { continue; } - loop: - for (int y = maxY; y >= 1; --y) { - final BlockType block = getBlockType(x, y, z); - switch (block.getInternalId()) { - case BlockID.COARSE_DIRT: - if (onlyNormalDirt) { - break loop; - } - this.setBlock(x, y, z, grass); - break loop; - case BlockID.DIRT: - this.setBlock(x, y, z, grass); - break loop; - case BlockID.WATER: - case BlockID.LAVA: - default: - if (block.getMaterial().isMovementBlocker()) { - break loop; - } + + for (int y = maxY; y > minY; --y) { + final BlockVector3 pt = BlockVector3.at(x, y, z); + final BlockState block = getBlock(pt); + + if (block.getBlockType() == BlockTypes.DIRT + || (!onlyNormalDirt && block.getBlockType() == BlockTypes.COARSE_DIRT)) { + if (setBlock(pt, grass)) { + ++affected; + } + break; + } else if (block.getBlockType() == BlockTypes.WATER || block.getBlockType() == BlockTypes.LAVA) { + break; + } else if (block.getBlockType().getMaterial().isMovementBlocker()) { + break; } } } } - return changes; + return affected; } /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index c6d94f35c..c41f244a5 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -34,6 +34,7 @@ import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.command.argument.HeightConverter; import com.sk89q.worldedit.command.util.CommandPermissions; import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator; import com.sk89q.worldedit.command.util.CreatureButcher; @@ -54,10 +55,12 @@ import com.sk89q.worldedit.function.operation.Operations; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.visitor.EntityVisitor; import com.sk89q.worldedit.internal.annotation.Direction; +import com.sk89q.worldedit.internal.annotation.VertHeight; import com.sk89q.worldedit.internal.expression.EvaluationException; import com.sk89q.worldedit.internal.expression.Expression; import com.sk89q.worldedit.internal.expression.ExpressionException; import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.math.Vector2; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CylinderRegion; import com.sk89q.worldedit.regions.Region; @@ -464,6 +467,7 @@ public class UtilityCommands { return affected; } + @Command( name = "snow", aliases = { "/snow" }, @@ -472,13 +476,27 @@ public class UtilityCommands { @CommandPermissions("worldedit.snow") @Logging(PLACEMENT) public int snow(Actor actor, LocalSession session, EditSession editSession, - @Arg(desc = "The radius of the circle to snow in", def = "10") - double size) throws WorldEditException { + @Arg(desc = "The radius of the cylinder to snow in", def = "10") + double size, + @Arg( + desc = "The height of the cylinder to snow in", + def = HeightConverter.DEFAULT_VALUE + ) + @VertHeight + int height, + @Switch(name = 's', desc = "Stack snow layers") + boolean stack) throws WorldEditException { size = Math.max(1, size); + height = Math.max(1, height); we.checkMaxRadius(size); - int affected = editSession.simulateSnow(session.getPlacementPosition(actor), size); - actor.printInfo(TranslatableComponent.of("worldedit.snow.created", TextComponent.of(affected))); + BlockVector3 position = session.getPlacementPosition(actor); + + CylinderRegion region = new CylinderRegion(position, Vector2.at(size, size), position.getBlockY() - height, position.getBlockY() + height); + int affected = editSession.simulateSnow(region, stack); + actor.printInfo(TranslatableComponent.of( + "worldedit.snow.created", TextComponent.of(affected) + )); return affected; } @@ -490,13 +508,22 @@ public class UtilityCommands { @CommandPermissions("worldedit.thaw") @Logging(PLACEMENT) public int thaw(Actor actor, LocalSession session, EditSession editSession, - @Arg(desc = "The radius of the circle to thaw in", def = "10") - double size) throws WorldEditException { + @Arg(desc = "The radius of the cylinder to thaw in", def = "10") + double size, + @Arg( + desc = "The height of the cylinder to thaw in", + def = HeightConverter.DEFAULT_VALUE + ) + @VertHeight + int height) throws WorldEditException { size = Math.max(1, size); + height = Math.max(1, height); we.checkMaxRadius(size); - int affected = editSession.thaw(session.getPlacementPosition(actor), size); - actor.printInfo(TranslatableComponent.of("worldedit.thaw.removed", TextComponent.of(affected))); + int affected = editSession.thaw(session.getPlacementPosition(actor), size, height); + actor.printInfo(TranslatableComponent.of( + "worldedit.thaw.removed", TextComponent.of(affected) + )); return affected; } @@ -508,16 +535,27 @@ public class UtilityCommands { @CommandPermissions("worldedit.green") @Logging(PLACEMENT) public int green(Actor actor, LocalSession session, EditSession editSession, - @Arg(desc = "The radius of the circle to convert in", def = "10") + @Arg(desc = "The radius of the cylinder to convert in", def = "10") double size, + @Arg( + desc = "The height of the cylinder to convert in", + def = HeightConverter.DEFAULT_VALUE + ) + @VertHeight + int height, @Switch(name = 'f', desc = "Also convert coarse dirt") boolean convertCoarse) throws WorldEditException { size = Math.max(1, size); + height = Math.max(1, height); we.checkMaxRadius(size); final boolean onlyNormalDirt = !convertCoarse; - final int affected = editSession.green(session.getPlacementPosition(actor), size, onlyNormalDirt); - actor.printInfo(TranslatableComponent.of("worldedit.green.changed", TextComponent.of(affected))); + final int affected = editSession.green( + session.getPlacementPosition(actor), size, height, onlyNormalDirt + ); + actor.printInfo(TranslatableComponent.of( + "worldedit.green.changed", TextComponent.of(affected) + )); return affected; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java index c1bc4d0f3..6dc337cb9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java @@ -23,12 +23,15 @@ import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.function.LayerFunction; import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.registry.state.BooleanProperty; import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypes; public class SnowSimulator implements LayerFunction { + public static final BooleanProperty snowy = (BooleanProperty) (Property) BlockTypes.GRASS_BLOCK.getProperty("snowy"); + private final BlockState ice = BlockTypes.ICE.getDefaultState(); private final BlockState snow = BlockTypes.SNOW.getDefaultState(); private final BlockState snowBlock = BlockTypes.SNOW_BLOCK.getDefaultState(); @@ -42,6 +45,7 @@ public class SnowSimulator implements LayerFunction { private int affected; public SnowSimulator(Extent extent, boolean stack) { + this.extent = extent; this.stack = stack; @@ -66,9 +70,8 @@ public class SnowSimulator implements LayerFunction { return true; } - // Can only place on full solid blocks - return block.getBlockType().getMaterial().isFullCube() - && block.getBlockType().getMaterial().isSolid(); + // Stop searching when we hit a movement blocker + return block.getBlockType().getMaterial().isMovementBlocker(); } @Override @@ -107,16 +110,25 @@ public class SnowSimulator implements LayerFunction { // We've hit the highest layer (If it doesn't contain current + 2 it means it's 1 away from full) if (!snowLayersProperty.getValues().contains(currentHeight + 2)) { if (this.extent.setBlock(abovePosition, snowBlock)) { + if (block.getStates().containsKey(snowy)) { + this.extent.setBlock(position, block.with(snowy, true)); + } this.affected++; } } else { if (this.extent.setBlock(abovePosition, above.with(snowLayersProperty, currentHeight + 1))) { + if (block.getStates().containsKey(snowy)) { + this.extent.setBlock(position, block.with(snowy, true)); + } this.affected++; } } return false; } if (this.extent.setBlock(abovePosition, snow)) { + if (block.getStates().containsKey(snowy)) { + this.extent.setBlock(position, block.with(snowy, true)); + } this.affected++; } return false;