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 7d07a5a23..b0f58edf0 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -27,11 +27,6 @@ import static com.sk89q.worldedit.regions.Regions.minimumBlockY; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.LazyBlock; -import com.sk89q.worldedit.world.block.BlockCategories; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockStateHolder; -import com.sk89q.worldedit.world.block.BlockType; -import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.event.extent.EditSessionEvent; @@ -108,6 +103,11 @@ import com.sk89q.worldedit.util.eventbus.EventBus; import com.sk89q.worldedit.world.NullWorld; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.biome.BaseBiome; +import com.sk89q.worldedit.world.block.BlockCategories; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockStateHolder; +import com.sk89q.worldedit.world.block.BlockType; +import com.sk89q.worldedit.world.block.BlockTypes; import java.util.ArrayList; import java.util.Collections; @@ -1137,35 +1137,28 @@ public class EditSession implements Extent { * * @param origin the original position * @param radius the radius to fix - * @param moving the block ID of the moving liquid - * @param stationary the block ID of the stationary liquid + * @param fluid the type of the fluid * @return number of blocks affected * @throws MaxChangedBlocksException thrown if too many blocks are changed */ - public int fixLiquid(Vector origin, double radius, BlockType moving, BlockType stationary) throws MaxChangedBlocksException { + public int fixLiquid(Vector origin, double radius, BlockType fluid) throws MaxChangedBlocksException { checkNotNull(origin); checkArgument(radius >= 0, "radius >= 0 required"); // Our origins can only be liquids - BlockMask liquidMask = new BlockMask( - this, - moving.getDefaultState(), - stationary.getDefaultState()); + BlockMask liquidMask = new BlockMask(this, new BlockState(fluid, new HashMap<>())); // But we will also visit air blocks - MaskIntersection blockMask = - new MaskUnion(liquidMask, - new BlockMask( - this, - BlockTypes.AIR.getDefaultState())); + MaskIntersection blockMask = new MaskUnion(liquidMask, new BlockMask(this, BlockTypes.AIR.getDefaultState())); // There are boundaries that the routine needs to stay in MaskIntersection mask = new MaskIntersection( new BoundedHeightMask(0, Math.min(origin.getBlockY(), getWorld().getMaxY())), new RegionMask(new EllipsoidRegion(null, origin, new Vector(radius, radius, radius))), - blockMask); + blockMask + ); - BlockReplace replace = new BlockReplace(this, new BlockPattern(stationary.getDefaultState())); + BlockReplace replace = new BlockReplace(this, new BlockPattern(fluid.getDefaultState())); NonRisingVisitor visitor = new NonRisingVisitor(mask, replace); // Around the origin in a 3x3 block 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 3fa96d9d8..4a428e0c2 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 @@ -170,9 +170,7 @@ public class UtilityCommands { double radius = Math.max(0, args.getDouble(0)); we.checkMaxRadius(radius); - // TODO Investigate with a real build of 1.13 - int affected = editSession.fixLiquid( - session.getPlacementPosition(player), radius, BlockTypes.LAVA, BlockTypes.LAVA); + int affected = editSession.fixLiquid(session.getPlacementPosition(player), radius, BlockTypes.LAVA); player.print(affected + " block(s) have been changed."); } @@ -189,9 +187,7 @@ public class UtilityCommands { double radius = Math.max(0, args.getDouble(0)); we.checkMaxRadius(radius); - // TODO Investigate with a real build of 1.13 - int affected = editSession.fixLiquid( - session.getPlacementPosition(player), radius, BlockTypes.WATER, BlockTypes.WATER); + int affected = editSession.fixLiquid(session.getPlacementPosition(player), radius, BlockTypes.WATER); player.print(affected + " block(s) have been changed."); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java index 4e025ff7e..faee49faf 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java @@ -19,6 +19,7 @@ package com.sk89q.worldedit.command.tool; +import com.google.common.collect.Lists; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalSession; @@ -26,10 +27,16 @@ import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Platform; +import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BlockState; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + /** * A mode that cycles the data values of supported blocks. */ @@ -40,6 +47,8 @@ public class BlockDataCyler implements DoubleActionBlockTool { return player.hasPermission("worldedit.tool.data-cycler"); } + private Map> selectedProperties = new HashMap<>(); + private boolean handleCycle(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked, boolean forward) { @@ -57,19 +66,36 @@ public class BlockDataCyler implements DoubleActionBlockTool { if (block.getStates().keySet().isEmpty()) { player.printError("That block's data cannot be cycled!"); } else { - BlockState newBlock = block; + Property currentProperty = selectedProperties.get(player.getUniqueId()); - // TODO Forward = cycle value, Backward = Next property - // int increment = forward ? 1 : -1; - // BaseBlock newBlock = new BaseBlock(type, BlockData.cycle(type, data, increment)); - EditSession editSession = session.createEditSession(player); + if (currentProperty == null || (forward && block.getState(currentProperty) == null)) { + currentProperty = block.getStates().keySet().stream().findFirst().get(); + selectedProperties.put(player.getUniqueId(), currentProperty); + } - try { - editSession.setBlock(clicked.toVector(), newBlock); - } catch (MaxChangedBlocksException e) { - player.printError("Max blocks change limit reached."); - } finally { - session.remember(editSession); + if (forward) { + block.getState(currentProperty); + int index = currentProperty.getValues().indexOf(block.getState(currentProperty)); + index = (index + 1) % currentProperty.getValues().size(); + BlockState newBlock = block.with(currentProperty, currentProperty.getValues().get(index)); + + EditSession editSession = session.createEditSession(player); + + try { + editSession.setBlock(clicked.toVector(), newBlock); + player.print("Value of " + currentProperty.getName() + " is now " + currentProperty.getValues().get(index).toString()); + } catch (MaxChangedBlocksException e) { + player.printError("Max blocks change limit reached."); + } finally { + session.remember(editSession); + } + } else { + List> properties = Lists.newArrayList(block.getStates().keySet()); + int index = properties.indexOf(currentProperty); + index = (index + 1) % properties.size(); + currentProperty = properties.get(index); + selectedProperties.put(player.getUniqueId(), currentProperty); + player.print("Now cycling " + currentProperty.getName()); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/MultiStageReorder.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/MultiStageReorder.java index 8edea8381..57be96226 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/MultiStageReorder.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/MultiStageReorder.java @@ -26,19 +26,26 @@ import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BlockType; import com.sk89q.worldedit.blocks.Blocks; -import com.sk89q.worldedit.world.block.BlockCategories; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockStateHolder; -import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.function.operation.BlockMapEntryPlacer; import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.OperationQueue; import com.sk89q.worldedit.function.operation.RunContext; +import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.collection.TupleArrayList; +import com.sk89q.worldedit.world.block.BlockCategories; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockStateHolder; +import com.sk89q.worldedit.world.block.BlockTypes; -import java.util.*; +import java.util.Deque; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; /** * Re-orders blocks into several stages. @@ -151,16 +158,16 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder assert (blockTypes.containsKey(current)); final BlockStateHolder blockStateHolder = blockTypes.get(current); -// final int data = baseBlock.getData(); if (BlockCategories.DOORS.contains(blockStateHolder.getBlockType())) { -// TODO if ((data & 0x8) == 0) { -// // Deal with lower door halves being attached to the floor AND the upper half -// BlockVector upperBlock = current.add(0, 1, 0).toBlockVector(); -// if (blocks.contains(upperBlock) && !walked.contains(upperBlock)) { -// walked.addFirst(upperBlock); -// } -// } + Property halfProperty = blockStateHolder.getBlockType().getProperty("half"); + if (blockStateHolder.getState(halfProperty).equals("lower")) { + // Deal with lower door halves being attached to the floor AND the upper half + BlockVector upperBlock = current.add(0, 1, 0).toBlockVector(); + if (blocks.contains(upperBlock) && !walked.contains(upperBlock)) { + walked.addFirst(upperBlock); + } + } } else if (BlockCategories.RAILS.contains(blockStateHolder.getBlockType())) { BlockVector lowerBlock = current.add(0, -1, 0).toBlockVector(); if (blocks.contains(lowerBlock) && !walked.contains(lowerBlock)) {