diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 5735238e0..0abc7058f 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -16,7 +16,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
package com.sk89q.worldedit;
import java.util.Map;
@@ -47,39 +46,38 @@ import com.sk89q.worldedit.patterns.*;
* @author sk89q
*/
public class EditSession {
+
/**
* Random number generator.
*/
private static Random prng = new Random();
-
/**
* World.
*/
protected LocalWorld world;
-
/**
* Stores the original blocks before modification.
*/
private DoubleArrayList original =
- new DoubleArrayList(
+ new DoubleArrayList(
true);
/**
* Stores the current blocks.
*/
private DoubleArrayList current =
- new DoubleArrayList(
+ new DoubleArrayList(
false);
/**
* Blocks that should be placed before last.
*/
private DoubleArrayList queueAfter =
- new DoubleArrayList(
+ new DoubleArrayList(
false);
/**
* Blocks that should be placed last.
*/
private DoubleArrayList queueLast =
- new DoubleArrayList(
+ new DoubleArrayList(
false);
/**
@@ -158,28 +156,28 @@ public class EditSession {
public boolean rawSetBlock(Vector pt, BaseBlock block) {
int y = pt.getBlockY();
int type = block.getType();
-
+
if (y < 0 || y > 127) {
return false;
}
-
+
// No invalid blocks
if (!world.isValidBlockType(type)) {
return false;
}
-
+
if (mask != null) {
if (!mask.matches(this, pt)) {
return false;
}
}
-
+
int existing = world.getBlockType(pt);
// Clear the container block so that it doesn't drop items
if (BlockType.isContainerBlock(existing) && blockBag == null) {
world.clearContainerBlockContents(pt);
- // Ice turns until water so this has to be done first
+ // Ice turns until water so this has to be done first
} else if (existing == BlockID.ICE) {
world.setBlockType(pt, 0);
}
@@ -205,7 +203,7 @@ public class EditSession {
}
}
}
-
+
boolean result;
if (BlockType.usesData(id)) {
@@ -222,30 +220,30 @@ public class EditSession {
}
}
//System.out.println(pt + "" +result);
-
+
if (id != 0) {
// Signs
if (block instanceof SignBlock) {
SignBlock signBlock = (SignBlock) block;
world.copyToWorld(pt, signBlock);
- // Chests
+ // Chests
} else if (block instanceof ChestBlock && blockBag == null) {
ChestBlock chestBlock = (ChestBlock) block;
world.copyToWorld(pt, chestBlock);
- // Furnaces
+ // Furnaces
} else if (block instanceof FurnaceBlock && blockBag == null) {
FurnaceBlock furnaceBlock = (FurnaceBlock) block;
world.copyToWorld(pt, furnaceBlock);
- // Dispenser
+ // Dispenser
} else if (block instanceof DispenserBlock && blockBag == null) {
DispenserBlock dispenserBlock = (DispenserBlock) block;
world.copyToWorld(pt, dispenserBlock);
- // Mob spawners
+ // Mob spawners
} else if (block instanceof MobSpawnerBlock) {
MobSpawnerBlock mobSpawnerblock = (MobSpawnerBlock) block;
world.copyToWorld(pt, mobSpawnerblock);
- // Note blocks
+ // Note blocks
} else if (block instanceof NoteBlock) {
NoteBlock noteBlock = (NoteBlock) block;
world.copyToWorld(pt, noteBlock);
@@ -337,14 +335,14 @@ public class EditSession {
// Place torches, etc. last
if (BlockType.shouldPlaceLast(block.getType())) {
queueLast.put(pt.toBlockVector(), block);
- return !(getBlockType(pt) == block.getType()
+ return !(getBlockType(pt) == block.getType()
&& getBlockData(pt) == block.getData());
// Destroy torches, etc. first
} else if (BlockType.shouldPlaceLast(getBlockType(pt))) {
rawSetBlock(pt, new BaseBlock(0));
} else {
queueAfter.put(pt.toBlockVector(), block);
- return !(getBlockType(pt) == block.getType()
+ return !(getBlockType(pt) == block.getType()
&& getBlockData(pt) == block.getData());
}
}
@@ -393,7 +391,7 @@ public class EditSession {
return world.getBlockType(pt);
}
-
+
public int getBlockData(Vector pt) {
// In the case of the queue, the block may have not actually been
// changed yet
@@ -423,27 +421,27 @@ public class EditSession {
SignBlock block = new SignBlock(type, data);
world.copyFromWorld(pt, block);
return block;
- // Chest
+ // Chest
} else if (type == BlockID.CHEST) {
ChestBlock block = new ChestBlock(data);
world.copyFromWorld(pt, block);
return block;
- // Furnace
+ // Furnace
} else if (type == BlockID.FURNACE || type == BlockID.BURNING_FURNACE) {
FurnaceBlock block = new FurnaceBlock(type, data);
world.copyFromWorld(pt, block);
return block;
- // Dispenser
+ // Dispenser
} else if (type == BlockID.DISPENSER) {
DispenserBlock block = new DispenserBlock(data);
world.copyFromWorld(pt, block);
return block;
- // Mob spawner
+ // Mob spawner
} else if (type == BlockID.MOB_SPAWNER) {
MobSpawnerBlock block = new MobSpawnerBlock(data);
world.copyFromWorld(pt, block);
return block;
- // Note block
+ // Note block
} else if (type == BlockID.NOTE_BLOCK) {
NoteBlock block = new NoteBlock(data);
world.copyFromWorld(pt, block);
@@ -536,7 +534,7 @@ public class EditSession {
}
queued = false;
}
-
+
/**
* Set fast mode.
*
@@ -545,7 +543,7 @@ public class EditSession {
public void setFastMode(boolean fastMode) {
this.fastMode = fastMode;
}
-
+
/**
* Return fast mode status.
*
@@ -1603,7 +1601,7 @@ public class EditSession {
if (setBlock(cur, stationaryBlock)){
++affected;
}
-
+
// Check radius
if (pos.distance(cur) > radius) {
continue;
@@ -1851,6 +1849,49 @@ public class EditSession {
return affected;
}
+ /**
+ * Makes a pyramid.
+ *
+ * @param pos
+ * @param block
+ * @param size
+ * @param filled
+ * @return number of blocks changed
+ * @throws MaxChangedBlocksException
+ */
+ public int makePyramid(Vector pos, Pattern block, int size,
+ boolean filled) throws MaxChangedBlocksException {
+ int affected = 0;
+
+ int height = size;
+
+ for (int y = 0; y <= height; ++y) {
+ size--;
+ for (int x = 0; x <= size; ++x) {
+ for (int z = 0; z <= size; ++z) {
+
+ if ((filled && z <= size && x <= size) || z == size || x == size) {
+
+ if (setBlock(pos.add(x, y, z), block)) {
+ ++affected;
+ }
+ if (setBlock(pos.add(-x, y, z), block)) {
+ ++affected;
+ }
+ if (setBlock(pos.add(x, y, -z), block)) {
+ ++affected;
+ }
+ if (setBlock(pos.add(-x, y, -z), block)) {
+ ++affected;
+ }
+ }
+ }
+ }
+ }
+
+ return affected;
+ }
+
/**
* Thaw.
*
@@ -1944,7 +1985,7 @@ public class EditSession {
|| id == 55 // Redstone wire
|| id == 59 // Crops
|| (id >= 63 && id <= 72) || id == 75 // Redstone
- // torch
+ // torch
|| id == 76 // Redstone torch
|| id == 77 // Stone button
|| id == 78 // Snow
@@ -2026,9 +2067,9 @@ public class EditSession {
*/
private void makePumpkinPatchVine(Vector basePos, Vector pos)
throws MaxChangedBlocksException {
- if (pos.distance(basePos) > 4)
+ if (pos.distance(basePos) > 4)
return;
- if (getBlockType(pos) != 0)
+ if (getBlockType(pos) != 0)
return;
for (int i = -1; i > -3; --i) {
@@ -2046,27 +2087,27 @@ public class EditSession {
int h = prng.nextInt(3) - 1;
if (t == 0) {
- if (prng.nextBoolean())
+ if (prng.nextBoolean())
makePumpkinPatchVine(basePos, pos.add(1, 0, 0));
- if (prng.nextBoolean())
+ if (prng.nextBoolean())
setBlockIfAir(pos.add(1, h, -1), new BaseBlock(18));
setBlockIfAir(pos.add(0, 0, -1), new BaseBlock(86));
} else if (t == 1) {
- if (prng.nextBoolean())
+ if (prng.nextBoolean())
makePumpkinPatchVine(basePos, pos.add(0, 0, 1));
- if (prng.nextBoolean())
+ if (prng.nextBoolean())
setBlockIfAir(pos.add(1, h, 0), new BaseBlock(18));
setBlockIfAir(pos.add(1, 0, 1), new BaseBlock(86));
} else if (t == 2) {
- if (prng.nextBoolean())
+ if (prng.nextBoolean())
makePumpkinPatchVine(basePos, pos.add(0, 0, -1));
- if (prng.nextBoolean())
+ if (prng.nextBoolean())
setBlockIfAir(pos.add(-1, h, 0), new BaseBlock(18));
setBlockIfAir(pos.add(-1, 0, 1), new BaseBlock(86));
} else if (t == 3) {
- if (prng.nextBoolean())
+ if (prng.nextBoolean())
makePumpkinPatchVine(basePos, pos.add(-1, 0, 0));
- if (prng.nextBoolean())
+ if (prng.nextBoolean())
setBlockIfAir(pos.add(-1, h, -1), new BaseBlock(18));
setBlockIfAir(pos.add(-1, 0, -1), new BaseBlock(86));
}
@@ -2089,7 +2130,7 @@ public class EditSession {
for (int z = basePos.getBlockZ() - size; z <= basePos.getBlockZ()
+ size; ++z) {
// Don't want to be in the ground
- if (!getBlock(new Vector(x, basePos.getBlockY(), z)).isAir())
+ if (!getBlock(new Vector(x, basePos.getBlockY(), z)).isAir())
continue;
// The gods don't want a pumpkin patch here
if (Math.random() < 0.98) {
@@ -2270,7 +2311,6 @@ public class EditSession {
* maximal height
* @return height of highest block found or 'minY'
*/
-
public int getHighestTerrainBlock(int x, int z, int minY, int maxY) {
for (int y = maxY; y >= minY; --y) {
Vector pt = new Vector(x, y, z);
@@ -2327,7 +2367,7 @@ public class EditSession {
public void setBlockBag(BlockBag blockBag) {
this.blockBag = blockBag;
}
-
+
/**
* Get the world.
*
@@ -2336,7 +2376,7 @@ public class EditSession {
public LocalWorld getWorld() {
return world;
}
-
+
/**
* Get the number of blocks changed, including repeated block changes.
*
diff --git a/src/main/java/com/sk89q/worldedit/commands/GenerationCommands.java b/src/main/java/com/sk89q/worldedit/commands/GenerationCommands.java
index e6b44e0d1..2284c8d11 100644
--- a/src/main/java/com/sk89q/worldedit/commands/GenerationCommands.java
+++ b/src/main/java/com/sk89q/worldedit/commands/GenerationCommands.java
@@ -178,4 +178,48 @@ public class GenerationCommands {
int affected = editSession.makePumpkinPatches(player.getPosition(), size);
player.print(affected + " pumpkin patches created.");
}
+
+ @Command(
+ aliases = {"/pyramid"},
+ usage = " ",
+ desc = "Generate a filled pyramid",
+ min = 2,
+ max = 2
+ )
+ @CommandPermissions({"worldedit.generation.pyramid"})
+ public static void pyramid(CommandContext args, WorldEdit we,
+ LocalSession session, LocalPlayer player, EditSession editSession)
+ throws WorldEditException {
+
+ Pattern block = we.getBlockPattern(player, args.getString(0));
+ int size = Math.max(1, args.getInteger(1));
+ Vector pos = session.getPlacementPosition(player);
+
+ int affected = editSession.makePyramid(pos, block, size, true);
+
+ player.findFreePosition();
+ player.print(affected + " block(s) have been created.");
+ }
+
+ @Command(
+ aliases = {"/hpyramid"},
+ usage = " ",
+ desc = "Generate a hollow pyramid",
+ min = 2,
+ max = 2
+ )
+ @CommandPermissions({"worldedit.generation.pyramid"})
+ public static void hpyramid(CommandContext args, WorldEdit we,
+ LocalSession session, LocalPlayer player, EditSession editSession)
+ throws WorldEditException {
+
+ Pattern block = we.getBlockPattern(player, args.getString(0));
+ int size = Math.max(1, args.getInteger(1));
+ Vector pos = session.getPlacementPosition(player);
+
+ int affected = editSession.makePyramid(pos, block, size, false);
+
+ player.findFreePosition();
+ player.print(affected + " block(s) have been created.");
+ }
}
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index af7c466ae..7b51f05d9 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -50,10 +50,19 @@ commands:
description: Modify block change limit
usage: /
permissions: 'worldedit.limit'
+ /gmask:
+ description: Set the global mask
+ usage: / [mask]
+ aliases: ['gmask']
+ permissions: 'worldedit.global-mask'
we:
description: WorldEdit commands
usage: /
aliases: ['worldedit']
+ /fast:
+ description: Toggle fast mode
+ usage: /
+ permissions: 'worldedit.fast'
toggleplace:
description:
usage: /
@@ -85,6 +94,10 @@ commands:
description: Generate pumpkin patches
usage: / [size]
permissions: 'worldedit.generation.pumpkins'
+ /pyramid:
+ description: Generate a filled pyramid
+ usage: / [inverted]
+ permissions: 'worldedit.generation.sphere'
/undo:
description: Undoes the last action
usage: / [times]
@@ -105,11 +118,11 @@ commands:
permissions: 'worldedit.navigation.unstuck'
ascend:
description: Go up a floor
- usage: /
+ usage: / [# of levels]
permissions: 'worldedit.navigation.ascend'
descend:
description: Go down a floor
- usage: /
+ usage: / [# of floors]
permissions: 'worldedit.navigation.descend'
ceil:
description: Go to the celing
@@ -143,6 +156,10 @@ commands:
description: Set a block on top of blocks in the region
usage: /
permissions: 'worldedit.region.overlay'
+ /naturalize:
+ description: 3 layers of dirt on top then rock below
+ usage: /
+ permissions: 'worldedit.region.naturalize'
/walls:
description: Build the four sides of the selection
usage: /
@@ -270,6 +287,10 @@ commands:
usage: / [pattern]
aliases: ['material', 'fill']
permissions: 'worldedit.brush.options.material'
+ range:
+ description: Set the brush range
+ usage: / [pattern]
+ permissions: 'worldedit.brush.options.range'
info:
description: Block information tool
usage: /
@@ -289,6 +310,11 @@ commands:
description: Block data cycler tool
usage: /
permissions: 'worldedit.tool.data-cycler'
+ floodfill:
+ description: Flood fill tool
+ usage: /
+ aliases: ['flood']
+ permissions: 'worldedit.tool.flood-fill'
brush:
description: Brush tool
usage: /