diff --git a/src/EditSession.java b/src/EditSession.java
index 865c3567f..ff7fcc649 100644
--- a/src/EditSession.java
+++ b/src/EditSession.java
@@ -21,6 +21,7 @@ import com.sk89q.worldedit.*;
import com.sk89q.worldedit.regions.*;
import com.sk89q.worldedit.blocks.*;
import com.sk89q.worldedit.data.*;
+import com.sk89q.worldedit.patterns.*;
import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
@@ -515,9 +516,16 @@ public class EditSession {
Vector min = region.getMinimumPoint();
Vector max = region.getMaximumPoint();
- for (int x = min.getBlockX(); x <= max.getBlockX(); x++) {
- for (int y = min.getBlockY(); y <= max.getBlockY(); y++) {
- for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
+ int minX = min.getBlockX();
+ int minY = min.getBlockY();
+ int minZ = min.getBlockZ();
+ int maxX = max.getBlockX();
+ int maxY = max.getBlockY();
+ int maxZ = max.getBlockZ();
+
+ for (int x = minX; x <= maxX; x++) {
+ for (int y = minY; y <= maxY; y++) {
+ for (int z = minZ; z <= maxZ; z++) {
Vector pt = new Vector(x, y, z);
if (setBlock(pt, block)) {
@@ -537,6 +545,45 @@ public class EditSession {
return affected;
}
+ /**
+ * Sets all the blocks inside a region to a certain block type.
+ *
+ * @param region
+ * @param block
+ * @return number of blocks affected
+ * @throws MaxChangedBlocksException
+ */
+ public int setBlocks(Region region, Pattern pattern)
+ throws MaxChangedBlocksException {
+ int affected = 0;
+
+ if (region instanceof CuboidRegion) {
+ // Doing this for speed
+ Vector min = region.getMinimumPoint();
+ Vector max = region.getMaximumPoint();
+
+ for (int x = min.getBlockX(); x <= max.getBlockX(); x++) {
+ for (int y = min.getBlockY(); y <= max.getBlockY(); y++) {
+ for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
+ Vector pt = new Vector(x, y, z);
+
+ if (setBlock(pt, pattern.next(pt))) {
+ affected++;
+ }
+ }
+ }
+ }
+ } else {
+ for (Vector pt : region) {
+ if (setBlock(pt, pattern.next(pt))) {
+ affected++;
+ }
+ }
+ }
+
+ return affected;
+ }
+
/**
* Replaces all the blocks of a type inside a region to another block type.
*
diff --git a/src/WorldEditListener.java b/src/WorldEditListener.java
index 6c4e0c323..28cefa0ce 100644
--- a/src/WorldEditListener.java
+++ b/src/WorldEditListener.java
@@ -17,6 +17,8 @@
* along with this program. If not, see .
*/
+import java.util.List;
+import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
@@ -31,6 +33,7 @@ import com.sk89q.worldedit.blocks.*;
import com.sk89q.worldedit.data.*;
import com.sk89q.worldedit.snapshots.*;
import com.sk89q.worldedit.regions.*;
+import com.sk89q.worldedit.patterns.*;
/**
* Plugin base.
@@ -267,8 +270,47 @@ public class WorldEditListener extends PluginListener {
return getBlock(id, false);
}
+ /**
+ * Get a list of blocks as a set. This returns a Pattern.
+ *
+ * @param list
+ * @return pattern
+ */
+ public Pattern getBlockPattern(String list)
+ throws UnknownItemException, DisallowedItemException {
+
+ String[] items = list.split(",");
+
+ if (items.length == 1) {
+ return new SingleBlockPattern(getBlock(items[0]));
+ }
+
+ List blockChances = new ArrayList();
+
+ for (String s : items) {
+ BaseBlock block;
+
+ double chance;
+ if (s.matches("[0-9]+(?:\\.(?:[0-9]+)?)?%.*")) {
+ String[] p = s.split("%");
+ chance = Double.parseDouble(p[0]);
+ block = getBlock(p[1]);
+ } else {
+ chance = 1;
+ block = getBlock(s);
+ }
+
+ blockChances.add(new BlockChance(block, chance));
+ }
+
+ return new RandomFillPattern(blockChances);
+ }
+
/**
* Get a list of blocks as a set.
+ *
+ * @param list
+ * @return set
*/
public Set getBlockIDs(String list) throws UnknownItemException,
DisallowedItemException {
@@ -723,8 +765,14 @@ public class WorldEditListener extends PluginListener {
// Replace all blocks in the region
} else if(split[0].equalsIgnoreCase("//set")) {
checkArgs(split, 1, 1, split[0]);
- BaseBlock block = getBlock(split[1]);
- int affected = editSession.setBlocks(session.getRegion(), block);
+ Pattern pattern = getBlockPattern(split[1]);
+ int affected;
+ if (pattern instanceof SingleBlockPattern) {
+ affected = editSession.setBlocks(session.getRegion(),
+ ((SingleBlockPattern)pattern).getBlock());
+ } else {
+ affected = editSession.setBlocks(session.getRegion(), pattern);
+ }
player.print(affected + " block(s) have been changed.");
return true;
diff --git a/src/com/sk89q/worldedit/patterns/BlockChance.java b/src/com/sk89q/worldedit/patterns/BlockChance.java
new file mode 100644
index 000000000..e28e80e97
--- /dev/null
+++ b/src/com/sk89q/worldedit/patterns/BlockChance.java
@@ -0,0 +1,63 @@
+// $Id$
+/*
+ * WorldEdit
+ * Copyright (C) 2010 sk89q
+ *
+ * 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 .
+*/
+
+package com.sk89q.worldedit.patterns;
+
+import com.sk89q.worldedit.blocks.BaseBlock;
+
+/**
+ * Gives a block a chance.
+ *
+ * @author sk89q
+ */
+public class BlockChance {
+ /**
+ * Block.
+ */
+ private BaseBlock block;
+ /**
+ * Chance. Can be any positive value.
+ */
+ private double chance;
+
+ /**
+ * Construct the object.
+ *
+ * @param block
+ * @param chance
+ */
+ public BlockChance(BaseBlock block, double chance) {
+ this.block = block;
+ this.chance = chance;
+ }
+
+ /**
+ * @return the block
+ */
+ public BaseBlock getBlock() {
+ return block;
+ }
+
+ /**
+ * @return the chance
+ */
+ public double getChance() {
+ return chance;
+ }
+}
diff --git a/src/com/sk89q/worldedit/patterns/Pattern.java b/src/com/sk89q/worldedit/patterns/Pattern.java
new file mode 100644
index 000000000..d5d84e4c6
--- /dev/null
+++ b/src/com/sk89q/worldedit/patterns/Pattern.java
@@ -0,0 +1,40 @@
+// $Id$
+/*
+ * WorldEdit
+ * Copyright (C) 2010 sk89q
+ *
+ * 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 .
+*/
+
+package com.sk89q.worldedit.patterns;
+
+import com.sk89q.worldedit.*;
+import com.sk89q.worldedit.blocks.BaseBlock;
+
+/**
+ * Used to get the block to set. This can be used to implement a pattern
+ * for when setting a region with blocks.
+ *
+ * @author sk89q
+ */
+public interface Pattern {
+ /**
+ * Get a block for a position. This return value of this method does
+ * not have to be consistent for the same position.
+ *
+ * @param pos
+ * @return
+ */
+ public BaseBlock next(Vector pos);
+}
diff --git a/src/com/sk89q/worldedit/patterns/RandomFillPattern.java b/src/com/sk89q/worldedit/patterns/RandomFillPattern.java
new file mode 100644
index 000000000..765134e79
--- /dev/null
+++ b/src/com/sk89q/worldedit/patterns/RandomFillPattern.java
@@ -0,0 +1,85 @@
+// $Id$
+/*
+ * WorldEdit
+ * Copyright (C) 2010 sk89q
+ *
+ * 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 .
+*/
+
+package com.sk89q.worldedit.patterns;
+
+import java.util.Random;
+import java.util.List;
+import java.util.ArrayList;
+import com.sk89q.worldedit.*;
+import com.sk89q.worldedit.blocks.BaseBlock;
+
+/**
+ * Pattern proportionally fills.
+ *
+ * @author sk89q
+ */
+public class RandomFillPattern implements Pattern {
+ /**
+ * Random number generator.
+ */
+ private static final Random random = new Random();
+ /**
+ * Blocks and their proportions.
+ */
+ private List blocks;
+
+ /**
+ * Construct the object.
+ *
+ * @param blockType
+ */
+ public RandomFillPattern(List blocks) {
+ double max = 0;
+
+ for (BlockChance block : blocks) {
+ max += block.getChance();
+ }
+
+ List finalBlocks = new ArrayList();
+
+ double i = 0;
+
+ for (BlockChance block : blocks) {
+ double v = block.getChance() / max;
+ i += v;
+ finalBlocks.add(new BlockChance(block.getBlock(), i));
+ }
+
+ this.blocks = finalBlocks;
+ }
+
+ /**
+ * Get next block.
+ *
+ * @param pos
+ * @return
+ */
+ public BaseBlock next(Vector pos) {
+ double r = random.nextDouble();
+
+ for (BlockChance block : blocks) {
+ if (r <= block.getChance()) {
+ return block.getBlock();
+ }
+ }
+
+ throw new RuntimeException("ProportionalFillPattern");
+ }
+}
diff --git a/src/com/sk89q/worldedit/patterns/SingleBlockPattern.java b/src/com/sk89q/worldedit/patterns/SingleBlockPattern.java
new file mode 100644
index 000000000..8bc996574
--- /dev/null
+++ b/src/com/sk89q/worldedit/patterns/SingleBlockPattern.java
@@ -0,0 +1,63 @@
+// $Id$
+/*
+ * WorldEdit
+ * Copyright (C) 2010 sk89q
+ *
+ * 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 .
+*/
+
+package com.sk89q.worldedit.patterns;
+
+import com.sk89q.worldedit.*;
+import com.sk89q.worldedit.blocks.BaseBlock;
+
+/**
+ * Always returns the same block type.
+ *
+ * @author sk89q
+ */
+public class SingleBlockPattern implements Pattern {
+ /**
+ * Block type.
+ */
+ private BaseBlock block;
+
+ /**
+ * Construct the object.
+ *
+ * @param blockType
+ */
+ public SingleBlockPattern(BaseBlock block) {
+ this.block = block;
+ }
+
+ /**
+ * Get next block.
+ *
+ * @param pos
+ * @return
+ */
+ public BaseBlock next(Vector pos) {
+ return block;
+ }
+
+ /**
+ * Get the block.
+ *
+ * @return
+ */
+ public BaseBlock getBlock() {
+ return block;
+ }
+}