Remove the final stage committer from the MultiStageReorder extent, as it caused issues and no longer appears to be entirely necessary.

This commit is contained in:
Matthew Miller 2018-12-13 20:30:54 +10:00
parent 502cfb338f
commit 700e41b706
5 changed files with 76 additions and 102 deletions

View File

@ -35,7 +35,7 @@ import com.sk89q.worldedit.world.World;
public class ItemUseParser extends SimpleCommand<Contextual<RegionFunction>> { public class ItemUseParser extends SimpleCommand<Contextual<RegionFunction>> {
private final ItemParser itemParser = addParameter(new ItemParser("item", "minecraft:dye:15")); private final ItemParser itemParser = addParameter(new ItemParser("item", "minecraft:bone_meal"));
@Override @Override
public Contextual<RegionFunction> call(CommandArgs args, CommandLocals locals) throws CommandException { public Contextual<RegionFunction> call(CommandArgs args, CommandLocals locals) throws CommandException {

View File

@ -62,7 +62,7 @@ public class NumberParser implements CommandExecutor<Number> {
@Override @Override
public List<String> getSuggestions(CommandArgs args, CommandLocals locals) throws MissingArgumentException { public List<String> getSuggestions(CommandArgs args, CommandLocals locals) throws MissingArgumentException {
String value = args.next(); String value = args.next();
return value.isEmpty() && defaultSuggestion != null ? Lists.newArrayList(defaultSuggestion) : Collections.<String>emptyList(); return value.isEmpty() && defaultSuggestion != null ? Lists.newArrayList(defaultSuggestion) : Collections.emptyList();
} }
@Override @Override

View File

@ -57,7 +57,7 @@ public class StringParser implements CommandExecutor<String> {
@Override @Override
public List<String> getSuggestions(CommandArgs args, CommandLocals locals) throws MissingArgumentException { public List<String> getSuggestions(CommandArgs args, CommandLocals locals) throws MissingArgumentException {
String value = args.next(); String value = args.next();
return value.isEmpty() && defaultSuggestion != null ? Lists.newArrayList(defaultSuggestion) : Collections.<String>emptyList(); return value.isEmpty() && defaultSuggestion != null ? Lists.newArrayList(defaultSuggestion) : Collections.emptyList();
} }
@Override @Override

View File

@ -24,11 +24,8 @@ import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.OperationQueue; import com.sk89q.worldedit.function.operation.OperationQueue;
import com.sk89q.worldedit.function.operation.RunContext;
import com.sk89q.worldedit.function.operation.SetLocatedBlocks; import com.sk89q.worldedit.function.operation.SetLocatedBlocks;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.LocatedBlock;
import com.sk89q.worldedit.util.collection.LocatedBlockList; import com.sk89q.worldedit.util.collection.LocatedBlockList;
import com.sk89q.worldedit.world.block.BlockCategories; import com.sk89q.worldedit.world.block.BlockCategories;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
@ -37,20 +34,16 @@ import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
/** /**
* Re-orders blocks into several stages. * Re-orders blocks into several stages.
*/ */
public class MultiStageReorder extends AbstractDelegateExtent implements ReorderingExtent { public class MultiStageReorder extends AbstractDelegateExtent implements ReorderingExtent {
private static Map<BlockType, PlacementPriority> priorityMap = new HashMap<>(); private static final Map<BlockType, PlacementPriority> priorityMap = new HashMap<>();
static { static {
// Late // Late
@ -129,7 +122,8 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
priorityMap.put(BlockTypes.OAK_TRAPDOOR, PlacementPriority.LAST); priorityMap.put(BlockTypes.OAK_TRAPDOOR, PlacementPriority.LAST);
priorityMap.put(BlockTypes.SPRUCE_TRAPDOOR, PlacementPriority.LAST); priorityMap.put(BlockTypes.SPRUCE_TRAPDOOR, PlacementPriority.LAST);
priorityMap.put(BlockTypes.DAYLIGHT_DETECTOR, PlacementPriority.LAST); priorityMap.put(BlockTypes.DAYLIGHT_DETECTOR, PlacementPriority.LAST);
priorityMap.put(BlockTypes.CAKE, PlacementPriority.LAST);
// Final // Final
BlockCategories.DOORS.getAll().forEach(type -> priorityMap.put(type, PlacementPriority.FINAL)); BlockCategories.DOORS.getAll().forEach(type -> priorityMap.put(type, PlacementPriority.FINAL));
BlockCategories.BANNERS.getAll().forEach(type -> priorityMap.put(type, PlacementPriority.FINAL)); BlockCategories.BANNERS.getAll().forEach(type -> priorityMap.put(type, PlacementPriority.FINAL));
@ -137,7 +131,6 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
priorityMap.put(BlockTypes.WALL_SIGN, PlacementPriority.FINAL); priorityMap.put(BlockTypes.WALL_SIGN, PlacementPriority.FINAL);
priorityMap.put(BlockTypes.CACTUS, PlacementPriority.FINAL); priorityMap.put(BlockTypes.CACTUS, PlacementPriority.FINAL);
priorityMap.put(BlockTypes.SUGAR_CANE, PlacementPriority.FINAL); priorityMap.put(BlockTypes.SUGAR_CANE, PlacementPriority.FINAL);
priorityMap.put(BlockTypes.CAKE, PlacementPriority.FINAL);
priorityMap.put(BlockTypes.PISTON_HEAD, PlacementPriority.FINAL); priorityMap.put(BlockTypes.PISTON_HEAD, PlacementPriority.FINAL);
priorityMap.put(BlockTypes.MOVING_PISTON, PlacementPriority.FINAL); priorityMap.put(BlockTypes.MOVING_PISTON, PlacementPriority.FINAL);
} }
@ -253,97 +246,9 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
} }
List<Operation> operations = new ArrayList<>(); List<Operation> operations = new ArrayList<>();
for (PlacementPriority priority : PlacementPriority.values()) { for (PlacementPriority priority : PlacementPriority.values()) {
if (priority != PlacementPriority.FINAL) { operations.add(new SetLocatedBlocks(getExtent(), stages.get(priority)));
operations.add(new SetLocatedBlocks(getExtent(), stages.get(priority)));
}
} }
operations.add(new FinalStageCommitter());
return new OperationQueue(operations); return new OperationQueue(operations);
} }
private class FinalStageCommitter implements Operation {
private Extent extent = getExtent();
private final Set<BlockVector3> blocks = new HashSet<>();
private final Map<BlockVector3, BlockStateHolder> blockTypes = new HashMap<>();
public FinalStageCommitter() {
for (LocatedBlock entry : stages.get(PlacementPriority.FINAL)) {
final BlockVector3 pt = entry.getLocation();
blocks.add(pt);
blockTypes.put(pt, entry.getBlock());
}
}
@Override
public Operation resume(RunContext run) throws WorldEditException {
while (!blocks.isEmpty()) {
BlockVector3 current = blocks.iterator().next();
final Deque<BlockVector3> walked = new LinkedList<>();
while (true) {
walked.addFirst(current);
assert (blockTypes.containsKey(current));
final BlockStateHolder blockStateHolder = blockTypes.get(current);
if (BlockCategories.DOORS.contains(blockStateHolder.getBlockType())) {
Property<Object> 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
BlockVector3 upperBlock = current.add(0, 1, 0);
if (blocks.contains(upperBlock) && !walked.contains(upperBlock)) {
walked.addFirst(upperBlock);
}
}
} else if (BlockCategories.RAILS.contains(blockStateHolder.getBlockType())) {
BlockVector3 lowerBlock = current.add(0, -1, 0);
if (blocks.contains(lowerBlock) && !walked.contains(lowerBlock)) {
walked.addFirst(lowerBlock);
}
}
if (!blockStateHolder.getBlockType().getMaterial().isFragileWhenPushed()) {
// Block is not attached to anything => we can place it
break;
}
// current = current.add(attachment.vector()).toBlockVector();
//
// if (!blocks.contains(current)) {
// // We ran outside the remaining set => assume we can place blocks on this
// break;
// }
//
if (walked.contains(current)) {
// Cycle detected => This will most likely go wrong, but there's nothing we can do about it.
break;
}
}
for (BlockVector3 pt : walked) {
extent.setBlock(pt, blockTypes.get(pt));
blocks.remove(pt);
}
}
for (LocatedBlockList stage : stages.values()) {
stage.clear();
}
return null;
}
@Override
public void cancel() {
}
@Override
public void addStatusMessages(List<String> messages) {
}
}
} }

View File

@ -0,0 +1,69 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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
* (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.extent.transform;
import static org.junit.Assert.assertEquals;
import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.math.transform.Transform;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import java.util.HashSet;
import java.util.Set;
@Ignore("A platform is currently required to get properties, preventing this test.")
public class BlockTransformExtentTest {
private static final Transform ROTATE_90 = new AffineTransform().rotateY(-90);
private static final Transform ROTATE_NEG_90 = new AffineTransform().rotateY(90);
private final Set<BlockType> ignored = new HashSet<>();
@Before
public void setUp() throws Exception {
BlockTypes.register(new BlockType("worldedit:test"));
}
@Test
public void testTransform() throws Exception {
for (BlockType type : BlockType.REGISTRY.values()) {
if (ignored.contains(type)) {
continue;
}
BlockState base = type.getDefaultState();
BlockState rotated = base;
for (int i = 1; i < 4; i++) {
rotated = BlockTransformExtent.transform(base, ROTATE_90);
}
assertEquals(base, rotated);
rotated = base;
for (int i = 1; i < 4; i++) {
rotated = BlockTransformExtent.transform(base, ROTATE_NEG_90);
}
assertEquals(base, rotated);
}
}
}