From a8eeacccd484611ab1cc10ffadd1e2cfe4908d5d Mon Sep 17 00:00:00 2001 From: aumgn Date: Sat, 17 Mar 2012 16:35:29 +0100 Subject: [PATCH] Add biome support Add a BiomeTypes interface Add methods in ServerInterface to retrieve the implemented BiomeTypes Add a getBiome method to LocalWorld and subclasses Add /biomeinfo & /biomelist commands Add a BiomeTypeMask Closes #181 --- .../java/com/sk89q/worldedit/BiomeType.java | 43 +++++++ .../java/com/sk89q/worldedit/BiomeTypes.java | 28 +++++ .../java/com/sk89q/worldedit/LocalWorld.java | 8 ++ .../com/sk89q/worldedit/ServerInterface.java | 7 ++ .../worldedit/UnknownBiomeTypeException.java | 17 +++ .../java/com/sk89q/worldedit/WorldEdit.java | 12 +- .../worldedit/bukkit/BukkitBiomeTypes.java | 47 +++++++ .../bukkit/BukkitServerInterface.java | 8 ++ .../sk89q/worldedit/bukkit/BukkitWorld.java | 13 ++ .../worldedit/commands/BiomeCommands.java | 119 ++++++++++++++++++ .../sk89q/worldedit/masks/BiomeTypeMask.java | 27 ++++ .../worldedit/spout/SpoutBiomeTypes.java | 26 ++++ .../worldedit/spout/SpoutServerInterface.java | 8 ++ .../com/sk89q/worldedit/spout/SpoutWorld.java | 12 ++ 14 files changed, 374 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/sk89q/worldedit/BiomeType.java create mode 100644 src/main/java/com/sk89q/worldedit/BiomeTypes.java create mode 100644 src/main/java/com/sk89q/worldedit/UnknownBiomeTypeException.java create mode 100644 src/main/java/com/sk89q/worldedit/bukkit/BukkitBiomeTypes.java create mode 100644 src/main/java/com/sk89q/worldedit/commands/BiomeCommands.java create mode 100644 src/main/java/com/sk89q/worldedit/masks/BiomeTypeMask.java create mode 100644 src/main/java/com/sk89q/worldedit/spout/SpoutBiomeTypes.java diff --git a/src/main/java/com/sk89q/worldedit/BiomeType.java b/src/main/java/com/sk89q/worldedit/BiomeType.java new file mode 100644 index 000000000..ae92e1ba5 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/BiomeType.java @@ -0,0 +1,43 @@ +package com.sk89q.worldedit; + +public class BiomeType { + + private String name; + + public BiomeType(String name) { + this.name = name; + } + + /** + * Get the name of the player. + * + * @return String + */ + public String getName() { + return name; + } + + /** + * Gets the hash code. + * + * @return hash code + */ + @Override + public int hashCode() { + return name.hashCode(); + } + + /** + * Returns true if equal. + * + * @param other + * @return whether the other object is equivalent + */ + @Override + public boolean equals(Object obj) { + if (obj instanceof BiomeType) { + return ((BiomeType) obj).name.equals(name); + } + return false; + } +} diff --git a/src/main/java/com/sk89q/worldedit/BiomeTypes.java b/src/main/java/com/sk89q/worldedit/BiomeTypes.java new file mode 100644 index 000000000..1a8d08081 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/BiomeTypes.java @@ -0,0 +1,28 @@ +package com.sk89q.worldedit; + +import java.util.List; + +public interface BiomeTypes { + + /** + * Returns if a biome with the given name is available. + * + * @param name + * @return + */ + boolean has(String name); + + /** + * Returns the biome type for the given name + * + * @return + */ + BiomeType get(String name) throws UnknownBiomeTypeException; + + /** + * Returns a list of all available biome types. + * + * @return + */ + List all(); +} diff --git a/src/main/java/com/sk89q/worldedit/LocalWorld.java b/src/main/java/com/sk89q/worldedit/LocalWorld.java index 39a1012ac..c9318d269 100644 --- a/src/main/java/com/sk89q/worldedit/LocalWorld.java +++ b/src/main/java/com/sk89q/worldedit/LocalWorld.java @@ -102,6 +102,14 @@ public abstract class LocalWorld { */ public abstract void setBlockDataFast(Vector pt, int data); + /** + * Get biome type + * + * @param pt + * @return + */ + public abstract BiomeType getBiome(Vector2D pt); + /** * set block type & data * @param pt diff --git a/src/main/java/com/sk89q/worldedit/ServerInterface.java b/src/main/java/com/sk89q/worldedit/ServerInterface.java index 8baaee076..84c25f00f 100644 --- a/src/main/java/com/sk89q/worldedit/ServerInterface.java +++ b/src/main/java/com/sk89q/worldedit/ServerInterface.java @@ -51,6 +51,13 @@ public abstract class ServerInterface { */ public abstract void reload(); + /** + * Returns all available biomes. + * + * @return + */ + public abstract BiomeTypes getBiomes(); + /** * Schedules the given task to be invoked once every period ticks * after an initial delay of delay ticks. diff --git a/src/main/java/com/sk89q/worldedit/UnknownBiomeTypeException.java b/src/main/java/com/sk89q/worldedit/UnknownBiomeTypeException.java new file mode 100644 index 000000000..d7bf9a4df --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/UnknownBiomeTypeException.java @@ -0,0 +1,17 @@ +package com.sk89q.worldedit; + +public class UnknownBiomeTypeException extends WorldEditException { + private static final long serialVersionUID = -6239229394330814896L; + + private String typeName; + + public UnknownBiomeTypeException(String typeName) { + super("Unknown " + typeName + " biome type."); + this.typeName = typeName; + } + + public String getTypeName() { + return typeName; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/WorldEdit.java b/src/main/java/com/sk89q/worldedit/WorldEdit.java index 362b15b05..afeae4af5 100644 --- a/src/main/java/com/sk89q/worldedit/WorldEdit.java +++ b/src/main/java/com/sk89q/worldedit/WorldEdit.java @@ -185,6 +185,7 @@ public class WorldEdit { commands.setInjector(new SimpleInjector(this)); + server.onCommandRegistration(commands.registerAndReturn(BiomeCommands.class), commands); server.onCommandRegistration(commands.registerAndReturn(ChunkCommands.class), commands); server.onCommandRegistration(commands.registerAndReturn(ClipboardCommands.class), commands); server.onCommandRegistration(commands.registerAndReturn(GeneralCommands.class), commands); @@ -589,7 +590,7 @@ public class WorldEdit { } } - private Mask getBlockMaskComponent(LocalPlayer player, LocalSession session, List masks, String component) throws IncompleteRegionException, UnknownItemException, DisallowedItemException { + private Mask getBlockMaskComponent(LocalPlayer player, LocalSession session, List masks, String component) throws WorldEditException { final char firstChar = component.charAt(0); switch (firstChar) { case '#': @@ -631,6 +632,15 @@ public class WorldEdit { return new UnderOverlayMask(ids, over); + case '$': + Set biomes = new HashSet(); + String[] biomesList = component.substring(1).split(","); + for (String biomeName : biomesList) { + BiomeType biome = server.getBiomes().get(biomeName); + biomes.add(biome); + } + return new BiomeTypeMask(biomes); + case '!': if (component.length() > 1) { return new InvertedBlockTypeMask(getBlockIDs(player, component.substring(1), true)); diff --git a/src/main/java/com/sk89q/worldedit/bukkit/BukkitBiomeTypes.java b/src/main/java/com/sk89q/worldedit/bukkit/BukkitBiomeTypes.java new file mode 100644 index 000000000..47bbc8759 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/bukkit/BukkitBiomeTypes.java @@ -0,0 +1,47 @@ +package com.sk89q.worldedit.bukkit; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import org.bukkit.block.Biome; + +import com.sk89q.worldedit.BiomeType; +import com.sk89q.worldedit.BiomeTypes; +import com.sk89q.worldedit.UnknownBiomeTypeException; + +public class BukkitBiomeTypes implements BiomeTypes { + + public BukkitBiomeTypes() { + } + + @Override + public boolean has(String name) { + try { + Biome.valueOf(name.toUpperCase(Locale.ENGLISH)); + return true; + } catch (IllegalArgumentException exc) { + return false; + } + } + + @Override + public BiomeType get(String name) throws UnknownBiomeTypeException { + try { + Biome biome = Biome.valueOf(name.toUpperCase(Locale.ENGLISH)); + return new BiomeType(biome.name()); + } catch (IllegalArgumentException exc) { + throw new UnknownBiomeTypeException(name); + } + } + + @Override + public List all() { + List biomes = new ArrayList(); + for (Biome biome : Biome.values()) { + biomes.add(new BiomeType(biome.name())); + } + return biomes; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java b/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java index 6ec0d1e05..d1ce298a3 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java @@ -36,6 +36,7 @@ import org.bukkit.Server; import org.bukkit.World; import org.bukkit.entity.EntityType; +import com.sk89q.worldedit.BiomeTypes; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.ServerInterface; @@ -43,10 +44,12 @@ public class BukkitServerInterface extends ServerInterface { public Server server; public WorldEditPlugin plugin; private CommandRegistration dynamicCommands; + private BukkitBiomeTypes biomes; public BukkitServerInterface(WorldEditPlugin plugin, Server server) { this.plugin = plugin; this.server = server; + this.biomes = new BukkitBiomeTypes(); dynamicCommands = new CommandRegistration(plugin); } @@ -67,6 +70,11 @@ public class BukkitServerInterface extends ServerInterface { plugin.loadConfiguration(); } + @Override + public BiomeTypes getBiomes() { + return biomes; + } + @Override public int schedule(long delay, long period, Runnable task) { return Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, task, delay, period); diff --git a/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index 6681aa500..1d59e7033 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -25,6 +25,7 @@ import java.util.Map; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.util.TreeGenerator; +import org.bukkit.block.Biome; import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.block.Chest; @@ -53,6 +54,7 @@ import org.bukkit.Material; import org.bukkit.TreeType; import org.bukkit.World; +import com.sk89q.worldedit.BiomeType; import com.sk89q.worldedit.BlockVector2D; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalWorld; @@ -195,6 +197,17 @@ public class BukkitWorld extends LocalWorld { return world.getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).getLightLevel(); } + /** + * Get biome type + * + * @param pt + * @return + */ + public BiomeType getBiome(Vector2D pt) { + Biome bukkitBiome = world.getBiome(pt.getBlockX(), pt.getBlockZ()); + return new BiomeType(bukkitBiome.name()); + } + /** * Regenerate an area. * diff --git a/src/main/java/com/sk89q/worldedit/commands/BiomeCommands.java b/src/main/java/com/sk89q/worldedit/commands/BiomeCommands.java new file mode 100644 index 000000000..727d6f5f8 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/commands/BiomeCommands.java @@ -0,0 +1,119 @@ +package com.sk89q.worldedit.commands; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.sk89q.minecraft.util.commands.Command; +import com.sk89q.minecraft.util.commands.CommandContext; +import com.sk89q.minecraft.util.commands.CommandPermissions; +import com.sk89q.worldedit.BiomeType; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.LocalWorld; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.Vector2D; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.regions.FlatRegion; +import com.sk89q.worldedit.regions.Region; + +public class BiomeCommands { + + private WorldEdit we; + + public BiomeCommands(WorldEdit we) { + this.we = we; + } + + @Command( + aliases = { "biomelist", "biomels" }, + usage = "[page]", + desc = "Gets all biomes available.", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.biome.list") + public void biomeList(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + int page; + int offset; + int count = 0; + + if (args.argsLength() == 0 || (page = args.getInteger(0)) < 2) { + page = 1; + offset = 0; + } else { + offset = (page - 1) * 19; + } + + List biomes = we.getServer().getBiomes().all(); + int totalPages = biomes.size() / 19 + 1; + player.print("Available Biomes (page " + page + "/" + totalPages + ") :"); + for (BiomeType biome : biomes) { + if (offset > 0) { + offset--; + } else { + player.print(" " + biome.getName()); + if (++count == 19) { + break; + } + } + } + } + + @Command( + aliases = { "biomeinfo" }, + usage = "", + flags = "ts", + desc = "Get the biome of the targeted block.", + help = + "Get the biome of the block.\n" + + "By default use the block you are currently in.\n" + + "-t use the block you are looking at.\n" + + "-s use all the blocks contained in your selection", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.biome.info") + public void biomeInfo(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + if (args.hasFlag('s')) { + LocalWorld world = player.getWorld(); + Region region = session.getSelection(world); + Set biomes = new HashSet(); + + if (region instanceof FlatRegion) { + for (Vector2D pt : ((FlatRegion) region).asFlatRegion()) { + biomes.add(world.getBiome(pt)); + } + } else { + for (Vector pt : region) { + biomes.add(world.getBiome(pt.toVector2D())); + } + } + + player.print("Biomes:"); + for (BiomeType biome : biomes) { + player.print(" " + biome.getName()); + } + } else { + Vector2D pos; + if (args.hasFlag('t')) { + Vector blockPosition = player.getBlockTrace(300); + if (blockPosition == null) { + player.printError("No block in sight!"); + return; + } + pos = blockPosition.toVector2D(); + } else { + pos = player.getPosition().toVector2D(); + } + BiomeType biome = player.getWorld().getBiome(pos); + player.print("Biome: " + biome.getName()); + } + } +} diff --git a/src/main/java/com/sk89q/worldedit/masks/BiomeTypeMask.java b/src/main/java/com/sk89q/worldedit/masks/BiomeTypeMask.java new file mode 100644 index 000000000..6331a7591 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/masks/BiomeTypeMask.java @@ -0,0 +1,27 @@ +package com.sk89q.worldedit.masks; + +import java.util.HashSet; +import java.util.Set; + +import com.sk89q.worldedit.BiomeType; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.Vector; + +public class BiomeTypeMask implements Mask { + + private Set biomes; + + public BiomeTypeMask() { + this(new HashSet()); + } + + public BiomeTypeMask(Set biomes) { + this.biomes = biomes; + } + + public boolean matches(EditSession editSession, Vector pos) { + BiomeType biome = editSession.getWorld().getBiome(pos.toVector2D()); + return biomes.contains(biome); + } + +} diff --git a/src/main/java/com/sk89q/worldedit/spout/SpoutBiomeTypes.java b/src/main/java/com/sk89q/worldedit/spout/SpoutBiomeTypes.java new file mode 100644 index 000000000..2a935e79a --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/spout/SpoutBiomeTypes.java @@ -0,0 +1,26 @@ +package com.sk89q.worldedit.spout; + +import java.util.Collections; +import java.util.List; + +import com.sk89q.worldedit.BiomeType; +import com.sk89q.worldedit.BiomeTypes; +import com.sk89q.worldedit.UnknownBiomeTypeException; + +public class SpoutBiomeTypes implements BiomeTypes { + + @Override + public boolean has(String name) { + return false; + } + + @Override + public BiomeType get(String name) throws UnknownBiomeTypeException { + throw new UnknownBiomeTypeException(name); + } + + @Override + public List all() { + return Collections.emptyList(); + } +} diff --git a/src/main/java/com/sk89q/worldedit/spout/SpoutServerInterface.java b/src/main/java/com/sk89q/worldedit/spout/SpoutServerInterface.java index a035a6ff9..f04ac176c 100644 --- a/src/main/java/com/sk89q/worldedit/spout/SpoutServerInterface.java +++ b/src/main/java/com/sk89q/worldedit/spout/SpoutServerInterface.java @@ -23,6 +23,7 @@ import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.CommandsManager; import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.BiomeTypes; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.ServerInterface; import org.spout.api.Game; @@ -40,10 +41,12 @@ public class SpoutServerInterface extends ServerInterface { public Game game; public WorldEditPlugin plugin; private final SpoutRawCommandExecutor executor; + private SpoutBiomeTypes biomes; public SpoutServerInterface(WorldEditPlugin plugin, Game game) { this.plugin = plugin; this.game = game; + this.biomes = new SpoutBiomeTypes(); this.executor = new SpoutRawCommandExecutor(plugin); } @@ -64,6 +67,11 @@ public class SpoutServerInterface extends ServerInterface { plugin.loadConfiguration(); } + @Override + public BiomeTypes getBiomes() { + return biomes; + } + @Override public int schedule(long delay, long period, Runnable task) { return game.getScheduler().scheduleSyncRepeatingTask(plugin, task, delay, period); diff --git a/src/main/java/com/sk89q/worldedit/spout/SpoutWorld.java b/src/main/java/com/sk89q/worldedit/spout/SpoutWorld.java index 56563176d..724c6442b 100644 --- a/src/main/java/com/sk89q/worldedit/spout/SpoutWorld.java +++ b/src/main/java/com/sk89q/worldedit/spout/SpoutWorld.java @@ -19,12 +19,14 @@ package com.sk89q.worldedit.spout; +import com.sk89q.worldedit.BiomeType; import com.sk89q.worldedit.BlockVector2D; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EntityType; import com.sk89q.worldedit.LocalWorld; 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.BaseItemStack; import com.sk89q.worldedit.regions.Region; @@ -176,6 +178,16 @@ public class SpoutWorld extends LocalWorld { return world.getBlockMaterial(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).getLightLevel(); } + /** + * Get biome type + * + * @param pt + * @return + */ + public BiomeType getBiome(Vector2D pt) { + return new BiomeType("Unknown"); + } + /** * Regenerate an area. *