From 6f116cd564518fb47d01a95e1644aa38f1443d34 Mon Sep 17 00:00:00 2001 From: sk89q Date: Sat, 1 Mar 2014 10:41:13 -0800 Subject: [PATCH] Added FloraPlacer FlatRegionFunction and //flora. --- .../worldedit/commands/RegionCommands.java | 42 +++++++- .../worldedit/generator/FloraPlacer.java | 95 +++++++++++++++++++ .../worldedit/generator/ForestGenerator.java | 30 +----- .../worldedit/generator/GroundGenerator.java | 69 ++++++++++++++ 4 files changed, 205 insertions(+), 31 deletions(-) create mode 100644 src/main/java/com/sk89q/worldedit/generator/FloraPlacer.java create mode 100644 src/main/java/com/sk89q/worldedit/generator/GroundGenerator.java diff --git a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java index 241b4f51b..f56b80b5d 100644 --- a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java +++ b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java @@ -29,6 +29,7 @@ import com.sk89q.worldedit.blocks.BlockID; import com.sk89q.worldedit.expression.ExpressionException; import com.sk89q.worldedit.filtering.GaussianKernel; import com.sk89q.worldedit.filtering.HeightMapFilter; +import com.sk89q.worldedit.generator.FloraPlacer; import com.sk89q.worldedit.masks.Mask; import com.sk89q.worldedit.patterns.Pattern; import com.sk89q.worldedit.patterns.SingleBlockPattern; @@ -404,7 +405,7 @@ public class RegionCommands { final Region region = session.getSelection(player.getWorld()); final Vector size = region.getMaximumPoint().subtract(region.getMinimumPoint()); - final Vector shiftVector = dir.multiply(count * (Math.abs(dir.dot(size))+1)); + final Vector shiftVector = dir.multiply(count * (Math.abs(dir.dot(size)) + 1)); region.shift(shiftVector); session.getRegionSelector(player.getWorld()).learnChanges(); @@ -517,7 +518,6 @@ public class RegionCommands { player.print(affected + " block(s) have been changed."); } - @Command( aliases = { "/forest" }, usage = "[type] [density]", @@ -554,4 +554,42 @@ public class RegionCommands { player.print(affected + " trees created."); } + @Command( + aliases = { "/flora" }, + usage = "[density]", + desc = "Make flora within the region", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.region.flora") + @Logging(REGION) + public void flora(CommandContext args, LocalSession session, LocalPlayer player, EditSession editSession) throws WorldEditException { + double density = args.argsLength() > 0 ? args.getDouble(0) / 100 : 0.1; + + Region region = session.getSelection(player.getWorld()); + FlatRegion flatRegion; + + if (region instanceof FlatRegion) { + flatRegion = (FlatRegion) region; + } else { + player.print("(The given region is not a 'flat region', so a cuboid region will be used instead.)"); + flatRegion = CuboidRegion.makeCuboid(region); + } + + int upperY = flatRegion.getMaximumY(); + int lowerY = flatRegion.getMinimumY(); + + FloraPlacer generator = new FloraPlacer(editSession, lowerY, upperY); + generator.setDensity(density); + int affected = 0; + + for (Vector2D pt : flatRegion.asFlatRegion()) { + if (generator.apply(pt)) { + affected++; + } + } + + player.print(affected + " flora created."); + } + } diff --git a/src/main/java/com/sk89q/worldedit/generator/FloraPlacer.java b/src/main/java/com/sk89q/worldedit/generator/FloraPlacer.java new file mode 100644 index 000000000..7174f8095 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/generator/FloraPlacer.java @@ -0,0 +1,95 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.generator; + +import com.sk89q.worldedit.EditSession; +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.patterns.BlockChance; +import com.sk89q.worldedit.patterns.Pattern; +import com.sk89q.worldedit.patterns.RandomFillPattern; + +import java.util.ArrayList; +import java.util.List; + +/** + * Generates flora over an applied area. + */ +public class FloraPlacer extends GroundGenerator { + + private final EditSession editSession; + private final Pattern desertPattern = getDesertPattern(); + private final Pattern temperatePattern = getTemperatePattern(); + + /** + * Create a new instance. + * + * @param editSession the edit session + * @param lowerY the lower Y + * @param upperY the upper Y (lowerY <= upperY) + */ + public FloraPlacer(EditSession editSession, int lowerY, int upperY) { + super(editSession, lowerY, upperY); + this.editSession = editSession; + } + + /** + * Get a pattern for plants to place inside a desert environment. + * + * @return a pattern that places flora + */ + public static Pattern getDesertPattern() { + List chance = new ArrayList(); + chance.add(new BlockChance(new BaseBlock(BlockID.DEAD_BUSH), 30)); + chance.add(new BlockChance(new BaseBlock(BlockID.CACTUS), 20)); + chance.add(new BlockChance(new BaseBlock(BlockID.AIR), 300)); + return new RandomFillPattern(chance); + } + + /** + * Get a pattern for plants to place inside a temperate environment. + * + * @return a pattern that places flora + */ + public static Pattern getTemperatePattern() { + List chance = new ArrayList(); + chance.add(new BlockChance(new BaseBlock(BlockID.LONG_GRASS, 1), 300)); + chance.add(new BlockChance(new BaseBlock(BlockID.RED_FLOWER), 5)); + chance.add(new BlockChance(new BaseBlock(BlockID.RED_FLOWER, 1), 1)); + chance.add(new BlockChance(new BaseBlock(BlockID.YELLOW_FLOWER), 5)); + return new RandomFillPattern(chance); + } + + @Override + protected boolean apply(Vector pt, BaseBlock block) throws WorldEditException { + if (block.getType() == BlockID.GRASS) { + editSession.setBlock(pt.add(0, 1, 0), temperatePattern.next(pt)); + return true; + } else if (block.getType() == BlockID.SAND) { + editSession.setBlock(pt.add(0, 1, 0), desertPattern.next(pt)); + return true; + } + + return false; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/generator/ForestGenerator.java b/src/main/java/com/sk89q/worldedit/generator/ForestGenerator.java index 0d0222cb0..fd4f960f3 100644 --- a/src/main/java/com/sk89q/worldedit/generator/ForestGenerator.java +++ b/src/main/java/com/sk89q/worldedit/generator/ForestGenerator.java @@ -22,21 +22,18 @@ package com.sk89q.worldedit.generator; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BlockID; -import com.sk89q.worldedit.operation.GroundFindingFunction; import com.sk89q.worldedit.util.TreeGenerator; /** * Generates forests by searching for the ground starting from the given upper Y * coordinate for every column given. */ -public class ForestGenerator extends GroundFindingFunction { +public class ForestGenerator extends GroundGenerator { private final TreeGenerator treeGenerator; private final EditSession editSession; - private double density; /** * Create a new instance. @@ -52,31 +49,6 @@ public class ForestGenerator extends GroundFindingFunction { this.treeGenerator = treeGenerator; } - /** - * Set the density (0 <= density <= 1) which indicates the percentage chance - * that a tree will spawn in each column. - * - * @return the density - */ - public double getDensity() { - return density; - } - - /** - * Get the density (0 <= density <= 1) which indicates the percentage chance - * that a tree will spawn in each column. - * - * @param density the density - */ - public void setDensity(double density) { - this.density = density; - } - - @Override - protected boolean shouldContinue(Vector2D pt) { - return Math.random() < density; - } - @Override protected boolean apply(Vector pt, BaseBlock block) throws MaxChangedBlocksException { int t = block.getType(); diff --git a/src/main/java/com/sk89q/worldedit/generator/GroundGenerator.java b/src/main/java/com/sk89q/worldedit/generator/GroundGenerator.java new file mode 100644 index 000000000..417bfe262 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/generator/GroundGenerator.java @@ -0,0 +1,69 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.generator; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.Vector2D; +import com.sk89q.worldedit.operation.GroundFindingFunction; + +/** + * An abstract implementation for generators. + */ +public abstract class GroundGenerator extends GroundFindingFunction { + + private double density; + + /** + * Create a new instance. + * + * @param editSession the edit session + * @param lowerY the lower Y + * @param upperY the upper Y (lowerY <= upperY) + */ + protected GroundGenerator(EditSession editSession, int lowerY, int upperY) { + super(editSession, lowerY, upperY); + } + + /** + * Set the density (0 <= density <= 1) which indicates the percentage chance + * that an object will spawn in each column. + * + * @return the density + */ + public double getDensity() { + return density; + } + + /** + * Get the density (0 <= density <= 1) which indicates the percentage chance + * that an object will spawn in each column. + * + * @param density the density + */ + public void setDensity(double density) { + this.density = density; + } + + @Override + protected boolean shouldContinue(Vector2D pt) { + return Math.random() < density; + } + +}