geforkt von Mirrors/FastAsyncWorldEdit
Broke up EditSession into many Extents.
Dieser Commit ist enthalten in:
Ursprung
10e672a94a
Commit
e7fe787b20
Datei-Diff unterdrückt, da er zu groß ist
Diff laden
@ -25,9 +25,11 @@ import com.sk89q.worldedit.foundation.Block;
|
|||||||
import com.sk89q.worldedit.foundation.World;
|
import com.sk89q.worldedit.foundation.World;
|
||||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
import com.sk89q.worldedit.function.operation.Operation;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.TreeGenerator;
|
import com.sk89q.worldedit.util.TreeGenerator;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.PriorityQueue;
|
import java.util.PriorityQueue;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
@ -618,4 +620,9 @@ public abstract class LocalWorld implements World, Extent {
|
|||||||
new BaseBlock(BlockID.WATER, -1));
|
new BaseBlock(BlockID.WATER, -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Operation commit() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
120
src/main/java/com/sk89q/worldedit/extent/BlockBagExtent.java
Normale Datei
120
src/main/java/com/sk89q/worldedit/extent/BlockBagExtent.java
Normale Datei
@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* 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 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.extent;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.LocalWorld;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.bags.BlockBag;
|
||||||
|
import com.sk89q.worldedit.bags.BlockBagException;
|
||||||
|
import com.sk89q.worldedit.bags.UnplaceableBlockException;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies a {@link BlockBag} to operations.
|
||||||
|
*/
|
||||||
|
public class BlockBagExtent extends ExtentDelegate {
|
||||||
|
|
||||||
|
private final LocalWorld world;
|
||||||
|
private Map<Integer, Integer> missingBlocks = new HashMap<Integer, Integer>();
|
||||||
|
private BlockBag blockBag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance.
|
||||||
|
*
|
||||||
|
* @param extent the extent
|
||||||
|
* @param world the world
|
||||||
|
* @param blockBag the block bag
|
||||||
|
*/
|
||||||
|
public BlockBagExtent(Extent extent, LocalWorld world, @Nullable BlockBag blockBag) {
|
||||||
|
super(extent);
|
||||||
|
checkNotNull(world);
|
||||||
|
this.world = world;
|
||||||
|
this.blockBag = blockBag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the block bag.
|
||||||
|
*
|
||||||
|
* @return a block bag, which may be null if none is used
|
||||||
|
*/
|
||||||
|
public @Nullable BlockBag getBlockBag() {
|
||||||
|
return blockBag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the block bag.
|
||||||
|
*
|
||||||
|
* @param blockBag a block bag, which may be null if none is used
|
||||||
|
*/
|
||||||
|
public void setBlockBag(@Nullable BlockBag blockBag) {
|
||||||
|
this.blockBag = blockBag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of missing blocks and clears the list for the next
|
||||||
|
* operation.
|
||||||
|
*
|
||||||
|
* @return a map of missing blocks
|
||||||
|
*/
|
||||||
|
public Map<Integer, Integer> popMissing() {
|
||||||
|
Map<Integer, Integer> missingBlocks = this.missingBlocks;
|
||||||
|
this.missingBlocks = new HashMap<Integer, Integer>();
|
||||||
|
return missingBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent) throws WorldEditException {
|
||||||
|
if (blockBag != null) {
|
||||||
|
final int type = block.getType();
|
||||||
|
final int existing = world.getBlockType(location);
|
||||||
|
|
||||||
|
if (type > 0) {
|
||||||
|
try {
|
||||||
|
blockBag.fetchPlacedBlock(type, 0);
|
||||||
|
} catch (UnplaceableBlockException e) {
|
||||||
|
return false;
|
||||||
|
} catch (BlockBagException e) {
|
||||||
|
if (!missingBlocks.containsKey(type)) {
|
||||||
|
missingBlocks.put(type, 1);
|
||||||
|
} else {
|
||||||
|
missingBlocks.put(type, missingBlocks.get(type) + 1);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existing > 0) {
|
||||||
|
try {
|
||||||
|
blockBag.storeDroppedBlock(existing, world.getBlockData(location));
|
||||||
|
} catch (BlockBagException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.setBlock(location, block, notifyAdjacent);
|
||||||
|
}
|
||||||
|
}
|
87
src/main/java/com/sk89q/worldedit/extent/BlockChangeLimiter.java
Normale Datei
87
src/main/java/com/sk89q/worldedit/extent/BlockChangeLimiter.java
Normale Datei
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* 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 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.extent;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Limits the number of blocks that can be changed before a
|
||||||
|
* {@link MaxChangedBlocksException} is thrown.
|
||||||
|
*/
|
||||||
|
public class BlockChangeLimiter extends ExtentDelegate {
|
||||||
|
|
||||||
|
private int limit;
|
||||||
|
private int count = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance.
|
||||||
|
*
|
||||||
|
* @param extent the extent
|
||||||
|
* @param limit the limit (>= 0) or -1 for no limit
|
||||||
|
*/
|
||||||
|
public BlockChangeLimiter(Extent extent, int limit) {
|
||||||
|
super(extent);
|
||||||
|
setLimit(limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the limit.
|
||||||
|
*
|
||||||
|
* @return the limit (>= 0) or -1 for no limit
|
||||||
|
*/
|
||||||
|
public int getLimit() {
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the limit.
|
||||||
|
*
|
||||||
|
* @param limit the limit (>= 0) or -1 for no limit
|
||||||
|
*/
|
||||||
|
public void setLimit(int limit) {
|
||||||
|
checkArgument(limit >= -1, "limit >= -1 required");
|
||||||
|
this.limit = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of blocks that have been counted so far.
|
||||||
|
*
|
||||||
|
* @return the number of blocks
|
||||||
|
*/
|
||||||
|
public int getCount() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent) throws WorldEditException {
|
||||||
|
if (limit >= 0) {
|
||||||
|
if (count >= limit) {
|
||||||
|
throw new MaxChangedBlocksException(limit);
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return super.setBlock(location, block, notifyAdjacent);
|
||||||
|
}
|
||||||
|
}
|
64
src/main/java/com/sk89q/worldedit/extent/BlockQuirkExtent.java
Normale Datei
64
src/main/java/com/sk89q/worldedit/extent/BlockQuirkExtent.java
Normale Datei
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* 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 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.extent;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.LocalWorld;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.blocks.BlockID;
|
||||||
|
import com.sk89q.worldedit.blocks.BlockType;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles various quirks when setting blocks, such as ice turning
|
||||||
|
* into water or containers dropping their contents.
|
||||||
|
*/
|
||||||
|
public class BlockQuirkExtent extends ExtentDelegate {
|
||||||
|
|
||||||
|
private final LocalWorld world;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance.
|
||||||
|
*
|
||||||
|
* @param extent the extent
|
||||||
|
* @param world the world
|
||||||
|
*/
|
||||||
|
public BlockQuirkExtent(Extent extent, LocalWorld world) {
|
||||||
|
super(extent);
|
||||||
|
checkNotNull(world);
|
||||||
|
this.world = world;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent) throws WorldEditException {
|
||||||
|
final int existing = world.getBlockType(location);
|
||||||
|
|
||||||
|
if (BlockType.isContainerBlock(existing)) {
|
||||||
|
world.clearContainerBlockContents(location); // Clear the container block so that it doesn't drop items
|
||||||
|
} else if (existing == BlockID.ICE) {
|
||||||
|
world.setBlockType(location, BlockID.AIR); // Ice turns until water so this has to be done first
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.setBlock(location, block, notifyAdjacent);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
56
src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java
Normale Datei
56
src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java
Normale Datei
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* 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 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.extent;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.history.change.BlockChange;
|
||||||
|
import com.sk89q.worldedit.history.changeset.ChangeSet;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores changes to a {@link ChangeSet}.
|
||||||
|
*/
|
||||||
|
public class ChangeSetExtent extends ExtentDelegate {
|
||||||
|
|
||||||
|
private final ChangeSet changeSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance.
|
||||||
|
*
|
||||||
|
* @param extent the extent
|
||||||
|
* @param changeSet the change set
|
||||||
|
*/
|
||||||
|
public ChangeSetExtent(Extent extent, ChangeSet changeSet) {
|
||||||
|
super(extent);
|
||||||
|
checkNotNull(changeSet);
|
||||||
|
this.changeSet = changeSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent) throws WorldEditException {
|
||||||
|
BaseBlock previous = getBlock(location);
|
||||||
|
changeSet.add(new BlockChange(location.toBlockVector(), previous, block));
|
||||||
|
return super.setBlock(location, block, notifyAdjacent);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
66
src/main/java/com/sk89q/worldedit/extent/ChunkLoadingExtent.java
Normale Datei
66
src/main/java/com/sk89q/worldedit/extent/ChunkLoadingExtent.java
Normale Datei
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* 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 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.extent;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.LocalWorld;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatically loads chunks when blocks are accessed.
|
||||||
|
*/
|
||||||
|
public class ChunkLoadingExtent extends ExtentDelegate {
|
||||||
|
|
||||||
|
private final LocalWorld world;
|
||||||
|
private boolean enabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance.
|
||||||
|
*
|
||||||
|
* @param extent the extent
|
||||||
|
* @param world the world
|
||||||
|
* @param enabled true to enable
|
||||||
|
*/
|
||||||
|
public ChunkLoadingExtent(Extent extent, LocalWorld world, boolean enabled) {
|
||||||
|
super(extent);
|
||||||
|
checkNotNull(world);
|
||||||
|
this.enabled = enabled;
|
||||||
|
this.world = world;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance with chunk loading enabled.
|
||||||
|
*
|
||||||
|
* @param extent the extent
|
||||||
|
* @param world the world
|
||||||
|
*/
|
||||||
|
public ChunkLoadingExtent(Extent extent, LocalWorld world) {
|
||||||
|
this(extent, world, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent) throws WorldEditException {
|
||||||
|
world.checkLoadedChunk(location);
|
||||||
|
return super.setBlock(location, block, notifyAdjacent);
|
||||||
|
}
|
||||||
|
}
|
63
src/main/java/com/sk89q/worldedit/extent/DataValidatorExtent.java
Normale Datei
63
src/main/java/com/sk89q/worldedit/extent/DataValidatorExtent.java
Normale Datei
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* 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 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.extent;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.LocalWorld;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates set data to prevent creating invalid blocks and such.
|
||||||
|
*/
|
||||||
|
public class DataValidatorExtent extends ExtentDelegate {
|
||||||
|
|
||||||
|
private final LocalWorld world;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance.
|
||||||
|
*
|
||||||
|
* @param extent the extent
|
||||||
|
* @param world the world
|
||||||
|
*/
|
||||||
|
public DataValidatorExtent(Extent extent, LocalWorld world) {
|
||||||
|
super(extent);
|
||||||
|
checkNotNull(world);
|
||||||
|
this.world = world;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent) throws WorldEditException {
|
||||||
|
final int y = location.getBlockY();
|
||||||
|
final int type = block.getType();
|
||||||
|
if (y < 0 || y > world.getMaxY()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No invalid blocks
|
||||||
|
if (!world.isValidBlockType(type)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.setBlock(location, block, notifyAdjacent);
|
||||||
|
}
|
||||||
|
}
|
@ -22,6 +22,9 @@ package com.sk89q.worldedit.extent;
|
|||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.function.operation.Operation;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A world, portion of a world, clipboard, or other object that can have blocks set or
|
* A world, portion of a world, clipboard, or other object that can have blocks set or
|
||||||
@ -76,4 +79,12 @@ public interface Extent {
|
|||||||
*/
|
*/
|
||||||
boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent) throws WorldEditException;
|
boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent) throws WorldEditException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an {@link Operation} that should be called to tie up loose ends
|
||||||
|
* (such as to commit changes in a buffer).
|
||||||
|
*
|
||||||
|
* @return an operation or null if there is none to execute
|
||||||
|
*/
|
||||||
|
@Nullable Operation commit();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
96
src/main/java/com/sk89q/worldedit/extent/ExtentDelegate.java
Normale Datei
96
src/main/java/com/sk89q/worldedit/extent/ExtentDelegate.java
Normale Datei
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* 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 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.extent;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.function.operation.Operation;
|
||||||
|
import com.sk89q.worldedit.function.operation.OperationQueue;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A base class for {@link Extent}s that merely passes extents onto another.
|
||||||
|
*/
|
||||||
|
public class ExtentDelegate implements Extent {
|
||||||
|
|
||||||
|
private final Extent extent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance.
|
||||||
|
*
|
||||||
|
* @param extent the extent
|
||||||
|
*/
|
||||||
|
public ExtentDelegate(Extent extent) {
|
||||||
|
checkNotNull(extent);
|
||||||
|
this.extent = extent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the extent.
|
||||||
|
*
|
||||||
|
* @return the extent
|
||||||
|
*/
|
||||||
|
public Extent getExtent() {
|
||||||
|
return extent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBlock getBlock(Vector location) {
|
||||||
|
return extent.getBlock(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBlockType(Vector location) {
|
||||||
|
return extent.getBlockType(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBlockData(Vector location) {
|
||||||
|
return extent.getBlockData(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent) throws WorldEditException {
|
||||||
|
return extent.setBlock(location, block, notifyAdjacent);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Operation commitBefore() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final @Nullable Operation commit() {
|
||||||
|
Operation ours = commitBefore();
|
||||||
|
Operation other = extent.commit();
|
||||||
|
if (ours != null && other != null) {
|
||||||
|
return new OperationQueue(ours, other);
|
||||||
|
} else if (ours != null) {
|
||||||
|
return ours;
|
||||||
|
} else if (other != null) {
|
||||||
|
return other;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
108
src/main/java/com/sk89q/worldedit/extent/FastModeExtent.java
Normale Datei
108
src/main/java/com/sk89q/worldedit/extent/FastModeExtent.java
Normale Datei
@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* 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 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.extent;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.BlockVector2D;
|
||||||
|
import com.sk89q.worldedit.LocalWorld;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.function.operation.Operation;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements "fast mode" which may skip physics, lighting, etc.
|
||||||
|
*/
|
||||||
|
public class FastModeExtent extends ExtentDelegate {
|
||||||
|
|
||||||
|
private final LocalWorld world;
|
||||||
|
private final Set<BlockVector2D> dirtyChunks = new HashSet<BlockVector2D>();
|
||||||
|
private boolean enabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance with fast mode enabled.
|
||||||
|
*
|
||||||
|
* @param world the world
|
||||||
|
*/
|
||||||
|
public FastModeExtent(LocalWorld world) {
|
||||||
|
this(world, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance.
|
||||||
|
*
|
||||||
|
* @param world the world
|
||||||
|
* @param enabled true to enable fast mode
|
||||||
|
*/
|
||||||
|
public FastModeExtent(LocalWorld world, boolean enabled) {
|
||||||
|
super(world);
|
||||||
|
checkNotNull(world);
|
||||||
|
this.world = world;
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether fast mode is enabled.
|
||||||
|
*
|
||||||
|
* @return true if fast mode is enabled
|
||||||
|
*/
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set fast mode enable status.
|
||||||
|
*
|
||||||
|
* @param enabled true to enable fast mode
|
||||||
|
*/
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent) throws WorldEditException {
|
||||||
|
dirtyChunks.add(new BlockVector2D(location.getBlockX() >> 4, location.getBlockZ() >> 4));
|
||||||
|
return super.setBlock(location, block, notifyAdjacent || enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Operation commitBefore() {
|
||||||
|
if (dirtyChunks.size() > 0) {
|
||||||
|
return new Operation() {
|
||||||
|
@Override
|
||||||
|
public Operation resume() throws WorldEditException {
|
||||||
|
world.fixAfterFastMode(dirtyChunks);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -38,14 +38,16 @@ import java.util.Map;
|
|||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Buffers changes to an {@link Extent} and allows later retrieval of buffered
|
* Buffers changes to an {@link Extent} and allows later retrieval for
|
||||||
* changes for actual setting.
|
* actual application of the changes.
|
||||||
|
* </p>
|
||||||
|
* This buffer will not attempt to return results from the buffer when
|
||||||
|
* accessor methods (such as {@link #getBlock(Vector)}) are called.
|
||||||
*/
|
*/
|
||||||
public class ExtentBuffer implements Extent, Pattern {
|
public class ForgetfulExtentBuffer extends ExtentDelegate implements Pattern {
|
||||||
|
|
||||||
private static final BaseBlock AIR = new BaseBlock(BlockID.AIR);
|
private static final BaseBlock AIR = new BaseBlock(BlockID.AIR);
|
||||||
|
|
||||||
private final Extent delegate;
|
|
||||||
private final Map<BlockVector, BaseBlock> buffer = new LinkedHashMap<BlockVector, BaseBlock>();
|
private final Map<BlockVector, BaseBlock> buffer = new LinkedHashMap<BlockVector, BaseBlock>();
|
||||||
private final Mask mask;
|
private final Mask mask;
|
||||||
private Vector min = null;
|
private Vector min = null;
|
||||||
@ -56,7 +58,7 @@ public class ExtentBuffer implements Extent, Pattern {
|
|||||||
*
|
*
|
||||||
* @param delegate the delegate extent for {@link Extent#getBlock(Vector)}, etc. calls
|
* @param delegate the delegate extent for {@link Extent#getBlock(Vector)}, etc. calls
|
||||||
*/
|
*/
|
||||||
public ExtentBuffer(Extent delegate) {
|
public ForgetfulExtentBuffer(Extent delegate) {
|
||||||
this(delegate, Masks.alwaysTrue());
|
this(delegate, Masks.alwaysTrue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,28 +69,13 @@ public class ExtentBuffer implements Extent, Pattern {
|
|||||||
* @param delegate the delegate extent for {@link Extent#getBlock(Vector)}, etc. calls
|
* @param delegate the delegate extent for {@link Extent#getBlock(Vector)}, etc. calls
|
||||||
* @param mask the mask
|
* @param mask the mask
|
||||||
*/
|
*/
|
||||||
public ExtentBuffer(Extent delegate, Mask mask) {
|
public ForgetfulExtentBuffer(Extent delegate, Mask mask) {
|
||||||
|
super(delegate);
|
||||||
checkNotNull(delegate);
|
checkNotNull(delegate);
|
||||||
checkNotNull(mask);
|
checkNotNull(mask);
|
||||||
this.delegate = delegate;
|
|
||||||
this.mask = mask;
|
this.mask = mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public BaseBlock getBlock(Vector location) {
|
|
||||||
return delegate.getBlock(location);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBlockType(Vector location) {
|
|
||||||
return delegate.getBlockType(location);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBlockData(Vector location) {
|
|
||||||
return delegate.getBlockData(location);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent) throws WorldEditException {
|
public boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent) throws WorldEditException {
|
||||||
// Update minimum
|
// Update minimum
|
||||||
@ -110,7 +97,7 @@ public class ExtentBuffer implements Extent, Pattern {
|
|||||||
buffer.put(blockVector, block);
|
buffer.put(blockVector, block);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return delegate.setBlock(location, block, notifyAdjacent);
|
return getExtent().setBlock(location, block, notifyAdjacent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
73
src/main/java/com/sk89q/worldedit/extent/MaskingExtent.java
Normale Datei
73
src/main/java/com/sk89q/worldedit/extent/MaskingExtent.java
Normale Datei
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* 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 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.extent;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
public class MaskingExtent extends ExtentDelegate {
|
||||||
|
|
||||||
|
private Mask mask;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance.
|
||||||
|
*
|
||||||
|
* @param extent the extent
|
||||||
|
* @param mask the mask
|
||||||
|
*/
|
||||||
|
public MaskingExtent(Extent extent, Mask mask) {
|
||||||
|
super(extent);
|
||||||
|
checkNotNull(mask);
|
||||||
|
this.mask = mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the mask.
|
||||||
|
*
|
||||||
|
* @return the mask
|
||||||
|
*/
|
||||||
|
public Mask getMask() {
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a mask.
|
||||||
|
*
|
||||||
|
* @param mask a mask
|
||||||
|
*/
|
||||||
|
public void setMask(Mask mask) {
|
||||||
|
checkNotNull(mask);
|
||||||
|
this.mask = mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent) throws WorldEditException {
|
||||||
|
if (mask.test(location)) {
|
||||||
|
return super.setBlock(location, block, notifyAdjacent);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
212
src/main/java/com/sk89q/worldedit/extent/reorder/SimpleBlockReorder.java
Normale Datei
212
src/main/java/com/sk89q/worldedit/extent/reorder/SimpleBlockReorder.java
Normale Datei
@ -0,0 +1,212 @@
|
|||||||
|
/*
|
||||||
|
* 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 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.extent.reorder;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterators;
|
||||||
|
import com.sk89q.worldedit.*;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.blocks.BlockID;
|
||||||
|
import com.sk89q.worldedit.blocks.BlockType;
|
||||||
|
import com.sk89q.worldedit.extent.ExtentDelegate;
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.function.operation.Operation;
|
||||||
|
import com.sk89q.worldedit.function.operation.OperationQueue;
|
||||||
|
import com.sk89q.worldedit.function.visitor.BlockMapEntryVisitor;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-orders blocks into several stages.
|
||||||
|
*/
|
||||||
|
public class SimpleBlockReorder extends ExtentDelegate {
|
||||||
|
|
||||||
|
private DoubleArrayList<BlockVector, BaseBlock> stage1 = new DoubleArrayList<BlockVector, BaseBlock>(false);
|
||||||
|
private DoubleArrayList<BlockVector, BaseBlock> stage2 = new DoubleArrayList<BlockVector, BaseBlock>(false);
|
||||||
|
private DoubleArrayList<BlockVector, BaseBlock> stage3 = new DoubleArrayList<BlockVector, BaseBlock>(false);
|
||||||
|
private boolean enabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance.
|
||||||
|
*
|
||||||
|
* @param extent the extent
|
||||||
|
* @param enabled true to enable
|
||||||
|
*/
|
||||||
|
public SimpleBlockReorder(Extent extent, boolean enabled) {
|
||||||
|
super(extent);
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance when the re-ordering is enabled.
|
||||||
|
*
|
||||||
|
* @param extent the extent
|
||||||
|
*/
|
||||||
|
public SimpleBlockReorder(Extent extent) {
|
||||||
|
this(extent, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether re-ordering is enabled.
|
||||||
|
*
|
||||||
|
* @return true if re-ordering is enabled
|
||||||
|
*/
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether re-ordering is enabled.
|
||||||
|
*
|
||||||
|
* @param enabled true if re-ordering is enabled
|
||||||
|
*/
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent) throws WorldEditException {
|
||||||
|
if (!enabled) {
|
||||||
|
return super.setBlock(location, block, notifyAdjacent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BlockType.shouldPlaceLast(block.getType())) {
|
||||||
|
// Place torches, etc. last
|
||||||
|
stage2.put(location.toBlockVector(), block);
|
||||||
|
return !(getBlockType(location) == block.getType() && getBlockData(location) == block.getData());
|
||||||
|
} else if (BlockType.shouldPlaceFinal(block.getType())) {
|
||||||
|
// Place signs, reed, etc even later
|
||||||
|
stage3.put(location.toBlockVector(), block);
|
||||||
|
return !(getBlockType(location) == block.getType() && getBlockData(location) == block.getData());
|
||||||
|
} else if (BlockType.shouldPlaceLast(getBlockType(location))) {
|
||||||
|
// Destroy torches, etc. first
|
||||||
|
super.setBlock(location, new BaseBlock(BlockID.AIR), notifyAdjacent);
|
||||||
|
return super.setBlock(location, block, notifyAdjacent);
|
||||||
|
} else {
|
||||||
|
stage1.put(location.toBlockVector(), block);
|
||||||
|
return !(getBlockType(location) == block.getType() && getBlockData(location) == block.getData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Operation commitBefore() {
|
||||||
|
return new OperationQueue(
|
||||||
|
new BlockMapEntryVisitor(
|
||||||
|
getExtent(),
|
||||||
|
Iterators.concat(stage1.iterator(), stage2.iterator())),
|
||||||
|
new Stage3Committer());
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Stage3Committer implements Operation {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Operation resume() throws WorldEditException {
|
||||||
|
Extent extent = getExtent();
|
||||||
|
|
||||||
|
final Set<BlockVector> blocks = new HashSet<BlockVector>();
|
||||||
|
final Map<BlockVector, BaseBlock> blockTypes = new HashMap<BlockVector, BaseBlock>();
|
||||||
|
for (Map.Entry<BlockVector, BaseBlock> entry : stage3) {
|
||||||
|
final BlockVector pt = entry.getKey();
|
||||||
|
blocks.add(pt);
|
||||||
|
blockTypes.put(pt, entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!blocks.isEmpty()) {
|
||||||
|
BlockVector current = blocks.iterator().next();
|
||||||
|
if (!blocks.contains(current)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Deque<BlockVector> walked = new LinkedList<BlockVector>();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
walked.addFirst(current);
|
||||||
|
|
||||||
|
assert (blockTypes.containsKey(current));
|
||||||
|
|
||||||
|
final BaseBlock baseBlock = blockTypes.get(current);
|
||||||
|
|
||||||
|
final int type = baseBlock.getType();
|
||||||
|
final int data = baseBlock.getData();
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case BlockID.WOODEN_DOOR:
|
||||||
|
case BlockID.IRON_DOOR:
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BlockID.MINECART_TRACKS:
|
||||||
|
case BlockID.POWERED_RAIL:
|
||||||
|
case BlockID.DETECTOR_RAIL:
|
||||||
|
case BlockID.ACTIVATOR_RAIL:
|
||||||
|
// Here, rails are hardcoded to be attached to the block below them.
|
||||||
|
// They're also attached to the block they're ascending towards via BlockType.getAttachment.
|
||||||
|
BlockVector lowerBlock = current.add(0, -1, 0).toBlockVector();
|
||||||
|
if (blocks.contains(lowerBlock) && !walked.contains(lowerBlock)) {
|
||||||
|
walked.addFirst(lowerBlock);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
final PlayerDirection attachment = BlockType.getAttachment(type, data);
|
||||||
|
if (attachment == null) {
|
||||||
|
// 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 remaing 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 (BlockVector pt : walked) {
|
||||||
|
extent.setBlock(pt, blockTypes.get(pt), true);
|
||||||
|
blocks.remove(pt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage1.clear();
|
||||||
|
stage2.clear();
|
||||||
|
stage3.clear();
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* 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 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.function.visitor;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.BlockVector;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.function.operation.Operation;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
public class BlockMapEntryVisitor implements Operation {
|
||||||
|
|
||||||
|
private final Extent extent;
|
||||||
|
private final Iterator<Map.Entry<BlockVector, BaseBlock>> iterator;
|
||||||
|
|
||||||
|
public BlockMapEntryVisitor(Extent extent, Iterator<Map.Entry<BlockVector, BaseBlock>> iterator) {
|
||||||
|
checkNotNull(extent);
|
||||||
|
checkNotNull(iterator);
|
||||||
|
this.extent = extent;
|
||||||
|
this.iterator = iterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Operation resume() throws WorldEditException {
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
Map.Entry<BlockVector, BaseBlock> entry = iterator.next();
|
||||||
|
extent.setBlock(entry.getKey(), entry.getValue(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
}
|
||||||
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren