geforkt von Mirrors/FastAsyncWorldEdit
Re-implemented /forestgen in Java. This version does not replace existing blocks. Undo system fixed.
Dieser Commit ist enthalten in:
Ursprung
4715a733c9
Commit
bd9a90f01d
@ -130,19 +130,38 @@ public class EditSession {
|
||||
*/
|
||||
public boolean setBlock(Vector pt, int blockType)
|
||||
throws MaxChangedBlocksException {
|
||||
if (!original.containsKey(pt)) {
|
||||
original.put(pt.toBlockPoint(), getBlock(pt));
|
||||
BlockVector blockPt = pt.toBlockVector();
|
||||
|
||||
if (!original.containsKey(blockPt)) {
|
||||
original.put(blockPt, getBlock(pt));
|
||||
|
||||
if (maxBlocks != -1 && original.size() > maxBlocks) {
|
||||
throw new MaxChangedBlocksException(maxBlocks);
|
||||
}
|
||||
}
|
||||
|
||||
current.put(pt.toBlockPoint(), blockType);
|
||||
current.put(pt.toBlockVector(), blockType);
|
||||
|
||||
return smartSetBlock(pt, blockType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a block only if there's no block already there.
|
||||
*
|
||||
* @param pt
|
||||
* @param blockType
|
||||
* @return if block was changed
|
||||
* @throws MaxChangedBlocksException
|
||||
*/
|
||||
public boolean setBlockIfAir(Vector pt, int blockType)
|
||||
throws MaxChangedBlocksException {
|
||||
if (getBlock(pt) != 0) {
|
||||
return false;
|
||||
} else {
|
||||
return setBlock(pt, blockType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually set the block. Will use queue.
|
||||
*
|
||||
@ -154,7 +173,7 @@ public class EditSession {
|
||||
if (queued) {
|
||||
if (blockType != 0 && queuedBlocks.contains(blockType)
|
||||
&& rawGetBlock(pt.add(0, -1, 0)) == 0) {
|
||||
queue.put(pt.toBlockPoint(), blockType);
|
||||
queue.put(pt.toBlockVector(), blockType);
|
||||
return getBlock(pt) != blockType;
|
||||
} else if (blockType == 0
|
||||
&& queuedBlocks.contains(rawGetBlock(pt.add(0, 1, 0)))) {
|
||||
@ -175,8 +194,10 @@ public class EditSession {
|
||||
// In the case of the queue, the block may have not actually been
|
||||
// changed yet
|
||||
if (queued) {
|
||||
if (current.containsKey(pt)) {
|
||||
return current.get(pt);
|
||||
BlockVector blockPt = pt.toBlockVector();
|
||||
|
||||
if (current.containsKey(blockPt)) {
|
||||
return current.get(blockPt);
|
||||
}
|
||||
}
|
||||
return etc.getMCServer().e.a(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
|
||||
@ -684,4 +705,114 @@ public class EditSession {
|
||||
|
||||
return affected;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a block by chance.
|
||||
*
|
||||
* @param pos
|
||||
* @param type
|
||||
* @param c 0-1 chance
|
||||
* @return whether a block was changed
|
||||
*/
|
||||
private boolean setChanceBlockIfAir(Vector pos, int type, double c)
|
||||
throws MaxChangedBlocksException {
|
||||
if (Math.random() <= c) {
|
||||
return setBlockIfAir(pos, type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a terrible looking pine tree.
|
||||
*
|
||||
* @param basePos
|
||||
*/
|
||||
private void makePineTree(Vector basePos)
|
||||
throws MaxChangedBlocksException {
|
||||
int trunkHeight = (int)Math.floor(Math.random() * 2) + 3;
|
||||
int height = (int)Math.floor(Math.random() * 5) + 8;
|
||||
|
||||
// Create trunk
|
||||
for (int i = 0; i < trunkHeight; i++) {
|
||||
if (!setBlockIfAir(basePos.add(0, i, 0), 17)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Move up
|
||||
basePos = basePos.add(0, trunkHeight, 0);
|
||||
|
||||
int pos2[] = {-2, 2};
|
||||
|
||||
// Create tree + leaves
|
||||
for (int i = 0; i < height; i++) {
|
||||
setBlockIfAir(basePos.add(0, i, 0), 17);
|
||||
|
||||
// Less leaves at these levels
|
||||
double chance = ((i == 0 || i == height - 1) ? 0.6 : 1);
|
||||
|
||||
// Inner leaves
|
||||
setChanceBlockIfAir(basePos.add(-1, i, 0), 18, chance);
|
||||
setChanceBlockIfAir(basePos.add(1, i, 0), 18, chance);
|
||||
setChanceBlockIfAir(basePos.add(0, i, -1), 18, chance);
|
||||
setChanceBlockIfAir(basePos.add(0, i, 1), 18, chance);
|
||||
setChanceBlockIfAir(basePos.add(1, i, 1), 18, chance);
|
||||
setChanceBlockIfAir(basePos.add(-1, i, 1), 18, chance);
|
||||
setChanceBlockIfAir(basePos.add(1, i, -1), 18, chance);
|
||||
setChanceBlockIfAir(basePos.add(-1, i, -1), 18, chance);
|
||||
|
||||
if (!(i == 0 || i == height - 1)) {
|
||||
for (int j = -2; j <= 2; j++) {
|
||||
setChanceBlockIfAir(basePos.add(-2, i, j), 18, 0.6);
|
||||
}
|
||||
for (int j = -2; j <= 2; j++) {
|
||||
setChanceBlockIfAir(basePos.add(2, i, j), 18, 0.6);
|
||||
}
|
||||
for (int j = -2; j <= 2; j++) {
|
||||
setChanceBlockIfAir(basePos.add(j, i, -2), 18, 0.6);
|
||||
}
|
||||
for (int j = -2; j <= 2; j++) {
|
||||
setChanceBlockIfAir(basePos.add(j, i, 2), 18, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setBlockIfAir(basePos.add(0, height, 0), 18);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a terrible looking pine forest.
|
||||
*
|
||||
* @param basePos
|
||||
* @param size
|
||||
* @return number of trees created
|
||||
*/
|
||||
public int makePineTreeForest(Vector basePos, int size)
|
||||
throws MaxChangedBlocksException {
|
||||
int affected = 0;
|
||||
|
||||
for (int x = basePos.getBlockX() - size; x <= basePos.getBlockX() + size; x++) {
|
||||
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)) != 0) { continue; }
|
||||
// The gods don't want a tree here
|
||||
if (Math.random() < 0.95) { continue; }
|
||||
|
||||
for (int y = basePos.getBlockY(); y >= basePos.getBlockY() - 10; y--) {
|
||||
// Check if we hit the ground
|
||||
int t = getBlock(new Vector(x, y, z));
|
||||
if (t == 2 || t == 3) {
|
||||
makePineTree(new Vector(x, y + 1, z));
|
||||
affected++;
|
||||
break;
|
||||
} else if (t != 0) { // Trees won't grow on this!
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return affected;
|
||||
}
|
||||
}
|
||||
|
@ -94,6 +94,7 @@ public class WorldEdit {
|
||||
commands.put("/editlimit", "[Num] - See documentation");
|
||||
commands.put("/editexpand", "<Dir> [Num] - Expands the selection");
|
||||
commands.put("/editcontract", "<Dir> [Num] - Contracts the selection");
|
||||
commands.put("/forestgen", "<Size> - Make an ugly pine tree forest");
|
||||
commands.put("/unstuck", "Go up to the first free spot");
|
||||
commands.put("/ascend", "Go up one level");
|
||||
commands.put("/descend", "Go dowm one level");
|
||||
@ -495,6 +496,16 @@ public class WorldEdit {
|
||||
|
||||
return true;
|
||||
|
||||
// Make pine tree forest
|
||||
} else if (split[0].equalsIgnoreCase("/forestgen")) {
|
||||
checkArgs(split, 0, 1, split[0]);
|
||||
int size = split.length > 1 ? Math.max(1, Integer.parseInt(split[1])) : 10;
|
||||
|
||||
int affected = editSession.makePineTreeForest(player.getPosition(), size);
|
||||
player.print(affected + " pine trees created.");
|
||||
|
||||
return true;
|
||||
|
||||
// Stack
|
||||
} else if (split[0].equalsIgnoreCase("/editstackair") ||
|
||||
split[0].equalsIgnoreCase("/editstack")) {
|
||||
|
@ -413,7 +413,7 @@ public class Vector {
|
||||
*
|
||||
* @return BlockVector
|
||||
*/
|
||||
public BlockVector toBlockPoint() {
|
||||
public BlockVector toBlockVector() {
|
||||
return new BlockVector(this);
|
||||
}
|
||||
}
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren