From 42be11009782e1d2ff8e311e8d4ce58944e07c07 Mon Sep 17 00:00:00 2001 From: sk89q Date: Thu, 17 Jul 2014 00:21:13 -0700 Subject: [PATCH] Implemented new biome API. --- .../worldedit/bukkit/BukkitBiomeRegistry.java | 79 +++++++ .../worldedit/bukkit/BukkitBiomeType.java | 106 ---------- .../worldedit/bukkit/BukkitBiomeTypes.java | 59 ------ .../bukkit/BukkitServerInterface.java | 10 +- .../sk89q/worldedit/bukkit/BukkitWorld.java | 48 ++--- .../worldedit/bukkit/BukkitWorldData.java | 53 +++++ .../bukkit/adapter/BukkitImplAdapter.java | 42 ++++ .../adapter/impl/CraftBukkit_v1_7_R2.class | Bin 15315 -> 16351 bytes .../adapter/impl/CraftBukkit_v1_7_R3.class | Bin 15315 -> 16351 bytes .../adapter/impl/CraftBukkit_v1_7_R4.class | Bin 15325 -> 16361 bytes .../worldedit/forge/ForgeBiomeRegistry.java | 107 ++++++++++ .../worldedit/forge/ForgeBiomeTypes.java | 87 -------- .../sk89q/worldedit/forge/ForgePlatform.java | 11 +- .../com/sk89q/worldedit/forge/ForgeWorld.java | 22 +- ...orgeBiomeType.java => ForgeWorldData.java} | 89 ++++---- .../sk89q/worldedit/forge/ForgeWorldEdit.java | 2 + .../java/com/sk89q/worldedit/EditSession.java | 15 +- .../worldedit/command/BiomeCommands.java | 144 ++++++------- .../worldedit/command/GenerationCommands.java | 11 +- .../extension/factory/DefaultMaskParser.java | 32 ++- .../extension/platform/Platform.java | 8 - .../extent/AbstractDelegateExtent.java | 12 ++ .../sk89q/worldedit/extent/InputExtent.java | 14 +- .../sk89q/worldedit/extent/NullExtent.java | 13 ++ .../sk89q/worldedit/extent/OutputExtent.java | 11 + .../extent/clipboard/BlockArrayClipboard.java | 12 ++ .../function/biome/BiomeReplace.java | 56 +++++ .../worldedit/function/mask/BiomeMask2D.java | 98 +++++++++ .../worldedit/function/mask/BlockMask.java | 8 + .../function/mask/BoundedHeightMask.java | 8 + .../function/mask/ExistingBlockMask.java | 8 + .../sk89q/worldedit/function/mask/Mask.java | 10 + .../function/mask/MaskIntersection.java | 20 +- .../function/mask/MaskIntersection2D.java | 100 +++++++++ .../worldedit/function/mask/MaskUnion.java | 17 ++ .../worldedit/function/mask/MaskUnion2D.java} | 52 +++-- .../sk89q/worldedit/function/mask/Masks.java | 111 ++++++++-- .../worldedit/function/mask/NoiseFilter.java | 8 + .../worldedit/function/mask/OffsetMask.java | 16 +- .../worldedit/function/mask/OffsetMask2D.java | 91 +++++++++ .../worldedit/function/mask/RegionMask.java | 8 + .../function/mask/SolidBlockMask.java | 8 + .../worldedit/internal/LocalWorldAdapter.java | 8 +- .../internal/ServerInterfaceAdapter.java | 6 - .../internal/command/WorldEditBinding.java | 34 +++- .../regions/shape/ArbitraryBiomeShape.java | 50 +++-- .../sk89q/worldedit/util/WeightedChoice.java | 118 +++++++++++ .../util/function/LevenshteinDistance.java | 192 ++++++++++++++++++ .../com/sk89q/worldedit/world/NullWorld.java | 12 +- .../java/com/sk89q/worldedit/world/World.java | 18 -- .../worldedit/world/biome/BaseBiome.java | 82 ++++++++ .../biome/BiomeData.java} | 21 +- .../worldedit/world/biome/BiomeName.java | 57 ++++++ .../sk89q/worldedit/world/biome/Biomes.java | 70 +++++++ .../registry/BiomeRegistry.java} | 35 ++-- .../world/registry/LegacyWorldData.java | 10 +- .../world/registry/NullBiomeRegistry.java | 57 ++++++ .../worldedit/world/registry/WorldData.java | 7 + 58 files changed, 1830 insertions(+), 553 deletions(-) create mode 100644 src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitBiomeRegistry.java delete mode 100644 src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitBiomeType.java delete mode 100644 src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitBiomeTypes.java create mode 100644 src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitWorldData.java create mode 100644 src/forge/java/com/sk89q/worldedit/forge/ForgeBiomeRegistry.java delete mode 100644 src/forge/java/com/sk89q/worldedit/forge/ForgeBiomeTypes.java rename src/forge/java/com/sk89q/worldedit/forge/{ForgeBiomeType.java => ForgeWorldData.java} (56%) create mode 100644 src/main/java/com/sk89q/worldedit/function/biome/BiomeReplace.java create mode 100644 src/main/java/com/sk89q/worldedit/function/mask/BiomeMask2D.java create mode 100644 src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection2D.java rename src/{legacy/java/com/sk89q/worldedit/masks/BiomeTypeMask.java => main/java/com/sk89q/worldedit/function/mask/MaskUnion2D.java} (54%) create mode 100644 src/main/java/com/sk89q/worldedit/function/mask/OffsetMask2D.java create mode 100644 src/main/java/com/sk89q/worldedit/util/WeightedChoice.java create mode 100644 src/main/java/com/sk89q/worldedit/util/function/LevenshteinDistance.java create mode 100644 src/main/java/com/sk89q/worldedit/world/biome/BaseBiome.java rename src/main/java/com/sk89q/worldedit/{BiomeType.java => world/biome/BiomeData.java} (74%) create mode 100644 src/main/java/com/sk89q/worldedit/world/biome/BiomeName.java create mode 100644 src/main/java/com/sk89q/worldedit/world/biome/Biomes.java rename src/main/java/com/sk89q/worldedit/{BiomeTypes.java => world/registry/BiomeRegistry.java} (56%) create mode 100644 src/main/java/com/sk89q/worldedit/world/registry/NullBiomeRegistry.java diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitBiomeRegistry.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitBiomeRegistry.java new file mode 100644 index 000000000..72e3379fc --- /dev/null +++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitBiomeRegistry.java @@ -0,0 +1,79 @@ +/* + * 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 Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.bukkit; + +import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; +import com.sk89q.worldedit.world.biome.BaseBiome; +import com.sk89q.worldedit.world.biome.BiomeData; +import com.sk89q.worldedit.world.registry.BiomeRegistry; +import org.bukkit.block.Biome; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * A biome registry for Bukkit. + */ +class BukkitBiomeRegistry implements BiomeRegistry { + + BukkitBiomeRegistry() { + } + + @Nullable + @Override + public BaseBiome createFromId(int id) { + return new BaseBiome(id); + } + + @Override + public List getBiomes() { + BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); + if (adapter != null) { + List biomes = new ArrayList(); + for (Biome biome : Biome.values()) { + int biomeId = adapter.getBiomeId(biome); + biomes.add(new BaseBiome(biomeId)); + } + return biomes; + } else { + return Collections.emptyList(); + } + } + + @Nullable + @Override + public BiomeData getData(BaseBiome biome) { + BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); + if (adapter != null) { + final Biome bukkitBiome = adapter.getBiome(biome.getId()); + return new BiomeData() { + @Override + public String getName() { + return bukkitBiome.name(); + } + }; + } else { + return null; + } + } + +} diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitBiomeType.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitBiomeType.java deleted file mode 100644 index 5962d54f8..000000000 --- a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitBiomeType.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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 Lesser 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 Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.bukkit; - -import java.util.Locale; - -import org.bukkit.block.Biome; - -import com.sk89q.worldedit.BiomeType; - -public enum BukkitBiomeType implements BiomeType { - - SWAMPLAND(Biome.SWAMPLAND), - FOREST(Biome.FOREST), - TAIGA(Biome.TAIGA), - DESERT(Biome.DESERT), - PLAINS(Biome.PLAINS), - HELL(Biome.HELL), - SKY(Biome.SKY), - RIVER(Biome.RIVER), - EXTREME_HILLS(Biome.EXTREME_HILLS), - OCEAN(Biome.OCEAN), - FROZEN_OCEAN(Biome.FROZEN_OCEAN), - FROZEN_RIVER(Biome.FROZEN_RIVER), - ICE_PLAINS(Biome.ICE_PLAINS), - ICE_MOUNTAINS(Biome.ICE_MOUNTAINS), - MUSHROOM_ISLAND(Biome.MUSHROOM_ISLAND), - MUSHROOM_SHORE(Biome.MUSHROOM_SHORE), - BEACH(Biome.BEACH), - DESERT_HILLS(Biome.DESERT_HILLS), - FOREST_HILLS(Biome.FOREST_HILLS), - TAIGA_HILLS(Biome.TAIGA_HILLS), - SMALL_MOUNTAINS(Biome.SMALL_MOUNTAINS), - JUNGLE(Biome.JUNGLE), - JUNGLE_HILLS(Biome.JUNGLE_HILLS), - JUNGLE_EDGE(Biome.JUNGLE_EDGE), - DEEP_OCEAN(Biome.DEEP_OCEAN), - STONE_BEACH(Biome.STONE_BEACH), - COLD_BEACH(Biome.COLD_BEACH), - BIRCH_FOREST(Biome.BIRCH_FOREST), - BIRCH_FOREST_HILLS(Biome.BIRCH_FOREST_HILLS), - ROOFED_FOREST(Biome.ROOFED_FOREST), - COLD_TAIGA(Biome.COLD_TAIGA), - COLD_TAIGA_HILLS(Biome.COLD_TAIGA_HILLS), - MEGA_TAIGA(Biome.MEGA_TAIGA), - MEGA_TAIGA_HILLS(Biome.MEGA_TAIGA_HILLS), - EXTREME_HILLS_PLUS(Biome.EXTREME_HILLS_PLUS), - SAVANNA(Biome.SAVANNA), - SAVANNA_PLATEAU(Biome.SAVANNA_PLATEAU), - MESA(Biome.MESA), - MESA_PLATEAU_FOREST(Biome.MESA_PLATEAU_FOREST), - MESA_PLATEAU(Biome.MESA_PLATEAU), - SUNFLOWER_PLAINS(Biome.SUNFLOWER_PLAINS), - DESERT_MOUNTAINS(Biome.DESERT_MOUNTAINS), - FLOWER_FOREST(Biome.FLOWER_FOREST), - TAIGA_MOUNTAINS(Biome.TAIGA_MOUNTAINS), - SWAMPLAND_MOUNTAINS(Biome.SWAMPLAND_MOUNTAINS), - ICE_PLAINS_SPIKES(Biome.ICE_PLAINS_SPIKES), - JUNGLE_MOUNTAINS(Biome.JUNGLE_MOUNTAINS), - JUNGLE_EDGE_MOUNTAINS(Biome.JUNGLE_EDGE_MOUNTAINS), - COLD_TAIGA_MOUNTAINS(Biome.COLD_TAIGA_MOUNTAINS), - SAVANNA_MOUNTAINS(Biome.SAVANNA_MOUNTAINS), - SAVANNA_PLATEAU_MOUNTAINS(Biome.SAVANNA_PLATEAU_MOUNTAINS), - MESA_BRYCE(Biome.MESA_BRYCE), - MESA_PLATEAU_FOREST_MOUNTAINS(Biome.MESA_PLATEAU_FOREST_MOUNTAINS), - MESA_PLATEAU_MOUNTAINS(Biome.MESA_PLATEAU_MOUNTAINS), - BIRCH_FOREST_MOUNTAINS(Biome.BIRCH_FOREST_MOUNTAINS), - BIRCH_FOREST_HILLS_MOUNTAINS(Biome.BIRCH_FOREST_HILLS_MOUNTAINS), - ROOFED_FOREST_MOUNTAINS(Biome.ROOFED_FOREST_MOUNTAINS), - MEGA_SPRUCE_TAIGA(Biome.MEGA_SPRUCE_TAIGA), - EXTREME_HILLS_MOUNTAINS(Biome.EXTREME_HILLS_MOUNTAINS), - EXTREME_HILLS_PLUS_MOUNTAINS(Biome.EXTREME_HILLS_PLUS_MOUNTAINS), - MEGA_SPRUCE_TAIGA_HILLS(Biome.MEGA_SPRUCE_TAIGA_HILLS); - - private Biome bukkitBiome; - - private BukkitBiomeType(Biome biome) { - this.bukkitBiome = biome; - } - - @Override - public String getName() { - return name().toLowerCase(Locale.ENGLISH); - } - - public Biome getBukkitBiome() { - return bukkitBiome; - } -} diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitBiomeTypes.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitBiomeTypes.java deleted file mode 100644 index 8a74fa91b..000000000 --- a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitBiomeTypes.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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 Lesser 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 Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.bukkit; - -import java.util.Arrays; -import java.util.List; -import java.util.Locale; - -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 { - BukkitBiomeType.valueOf(name.toUpperCase(Locale.ENGLISH)); - return true; - } catch (IllegalArgumentException exc) { - return false; - } - } - - @Override - public BiomeType get(String name) throws UnknownBiomeTypeException { - try { - return BukkitBiomeType.valueOf(name.toUpperCase(Locale.ENGLISH)); - } catch (IllegalArgumentException exc) { - throw new UnknownBiomeTypeException(name); - } - } - - @Override - public List all() { - return Arrays.asList(BukkitBiomeType.values()); - } - -} diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java index 1bf4c6a61..adb25c7de 100644 --- a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java +++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java @@ -21,7 +21,6 @@ package com.sk89q.worldedit.bukkit; import com.sk89q.bukkit.util.CommandInfo; import com.sk89q.bukkit.util.CommandRegistration; -import com.sk89q.worldedit.BiomeTypes; import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.ServerInterface; @@ -50,13 +49,13 @@ public class BukkitServerInterface extends ServerInterface implements MultiUserP public Server server; public WorldEditPlugin plugin; private CommandRegistration dynamicCommands; - private BukkitBiomeTypes biomes; + private BukkitBiomeRegistry biomes; private boolean hookingEvents; public BukkitServerInterface(WorldEditPlugin plugin, Server server) { this.plugin = plugin; this.server = server; - this.biomes = new BukkitBiomeTypes(); + this.biomes = new BukkitBiomeRegistry(); dynamicCommands = new CommandRegistration(plugin); } @@ -81,11 +80,6 @@ public class BukkitServerInterface extends ServerInterface implements MultiUserP 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/bukkit/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index 170ceacb6..c95e4130d 100644 --- a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -19,7 +19,6 @@ package com.sk89q.worldedit.bukkit; -import com.sk89q.worldedit.BiomeType; import com.sk89q.worldedit.BlockVector2D; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalWorld; @@ -34,7 +33,7 @@ import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.TreeGenerator; -import com.sk89q.worldedit.world.registry.LegacyWorldData; +import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.registry.WorldData; import org.bukkit.Effect; import org.bukkit.Material; @@ -161,25 +160,6 @@ public class BukkitWorld extends LocalWorld { return getWorld().getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).getLightLevel(); } - @Override - public BiomeType getBiome(Vector2D pt) { - Biome bukkitBiome = getWorld().getBiome(pt.getBlockX(), pt.getBlockZ()); - try { - return BukkitBiomeType.valueOf(bukkitBiome.name()); - } catch (IllegalArgumentException exc) { - return BiomeType.UNKNOWN; - } - } - - @Override - public void setBiome(Vector2D pt, BiomeType biome) { - if (biome instanceof BukkitBiomeType) { - Biome bukkitBiome; - bukkitBiome = ((BukkitBiomeType) biome).getBukkitBiome(); - getWorld().setBiome(pt.getBlockX(), pt.getBlockZ(), bukkitBiome); - } - } - @Override public boolean regenerate(Region region, EditSession editSession) { BaseBlock[] history = new BaseBlock[16 * 16 * (getMaxY() + 1)]; @@ -413,7 +393,7 @@ public class BukkitWorld extends LocalWorld { @Override public WorldData getWorldData() { - return LegacyWorldData.getInstance(); + return BukkitWorldData.getInstance(); } @Override @@ -451,6 +431,29 @@ public class BukkitWorld extends LocalWorld { return new LazyBlock(bukkitBlock.getTypeId(), bukkitBlock.getData(), this, position); } + @Override + public BaseBiome getBiome(Vector2D position) { + BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); + if (adapter != null) { + int id = adapter.getBiomeId(getWorld().getBiome(position.getBlockX(), position.getBlockZ())); + return new BaseBiome(id); + } else { + return new BaseBiome(0); + } + } + + @Override + public boolean setBiome(Vector2D position, BaseBiome biome) { + BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); + if (adapter != null) { + Biome bukkitBiome = adapter.getBiome(biome.getId()); + getWorld().setBiome(position.getBlockX(), position.getBlockZ(), bukkitBiome); + return true; + } else { + return false; + } + } + /** * @deprecated Use {@link #setBlock(Vector, BaseBlock, boolean)} */ @@ -458,5 +461,4 @@ public class BukkitWorld extends LocalWorld { public boolean setBlock(Vector pt, com.sk89q.worldedit.foundation.Block block, boolean notifyAdjacent) throws WorldEditException { return setBlock(pt, (BaseBlock) block, notifyAdjacent); } - } diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitWorldData.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitWorldData.java new file mode 100644 index 000000000..6d747f4aa --- /dev/null +++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitWorldData.java @@ -0,0 +1,53 @@ +/* + * 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 Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.bukkit; + +import com.sk89q.worldedit.world.registry.BiomeRegistry; +import com.sk89q.worldedit.world.registry.LegacyWorldData; + +/** + * World data for the Bukkit platform. + */ +class BukkitWorldData extends LegacyWorldData { + + private static final BukkitWorldData INSTANCE = new BukkitWorldData(); + private final BiomeRegistry biomeRegistry = new BukkitBiomeRegistry(); + + /** + * Create a new instance. + */ + BukkitWorldData() { + } + + @Override + public BiomeRegistry getBiomeRegistry() { + return biomeRegistry; + } + + /** + * Get a static instance. + * + * @return an instance + */ + public static BukkitWorldData getInstance() { + return INSTANCE; + } + +} diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java index a5e293593..04113a6d5 100644 --- a/src/bukkit/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java +++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java @@ -22,6 +22,8 @@ package com.sk89q.worldedit.bukkit.adapter; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.entity.BaseEntity; import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Biome; import org.bukkit.entity.Entity; import javax.annotation.Nullable; @@ -31,6 +33,46 @@ import javax.annotation.Nullable; */ public interface BukkitImplAdapter { + /** + * Get the block ID for the given material. + * + *

Returns 0 if it is not known or it doesn't exist.

+ * + * @param material the material + * @return the block ID + */ + int getBlockId(Material material); + + /** + * Get the material for the given block ID. + * + *

Returns {@link Material#AIR} if it is not known or it doesn't exist.

+ * + * @param id the block ID + * @return the material + */ + Material getMaterial(int id); + + /** + * Get the biome ID for the given biome. + * + *

Returns 0 if it is not known or it doesn't exist.

+ * + * @param biome biome + * @return the biome ID + */ + int getBiomeId(Biome biome); + + /** + * Get the biome ID for the given biome ID.. + * + *

Returns {@link Biome#OCEAN} if it is not known or it doesn't exist.

+ * + * @param id the biome ID + * @return the biome + */ + Biome getBiome(int id); + /** * Get the block at the given location. * diff --git a/src/bukkit/resources/com/sk89q/worldedit/bukkit/adapter/impl/CraftBukkit_v1_7_R2.class b/src/bukkit/resources/com/sk89q/worldedit/bukkit/adapter/impl/CraftBukkit_v1_7_R2.class index bc003177317356af89ab80535a66992f4449ec02..20b3c1930a150e2fcceed10e7434fa6528513eca 100644 GIT binary patch delta 7420 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 PEFb;@OMvJ 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 diff --git a/src/bukkit/resources/com/sk89q/worldedit/bukkit/adapter/impl/CraftBukkit_v1_7_R3.class b/src/bukkit/resources/com/sk89q/worldedit/bukkit/adapter/impl/CraftBukkit_v1_7_R3.class index 188b0becc9399d43d50f461512c57693698d3b84..1f8cc436fb9b145c0b8f0c7ef9a2e518ff8e5926 100644 GIT binary patch delta 7420 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 PEFb;@OMvJ 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 diff --git a/src/bukkit/resources/com/sk89q/worldedit/bukkit/adapter/impl/CraftBukkit_v1_7_R4.class b/src/bukkit/resources/com/sk89q/worldedit/bukkit/adapter/impl/CraftBukkit_v1_7_R4.class index b60c4898d0f356b5297f750d0f52ead7a38c93e3..f9eb46a5da3e8d2c53e45596647c373e31acf708 100644 GIT binary patch delta 7427 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 delta 6474 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 diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgeBiomeRegistry.java b/src/forge/java/com/sk89q/worldedit/forge/ForgeBiomeRegistry.java new file mode 100644 index 000000000..7f0597313 --- /dev/null +++ b/src/forge/java/com/sk89q/worldedit/forge/ForgeBiomeRegistry.java @@ -0,0 +1,107 @@ +/* + * 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 Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.forge; + +import com.google.common.collect.HashBiMap; +import com.sk89q.worldedit.world.biome.BaseBiome; +import com.sk89q.worldedit.world.biome.BiomeData; +import com.sk89q.worldedit.world.registry.BiomeRegistry; +import net.minecraft.world.biome.BiomeGenBase; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Provides access to biome data in Forge. + */ +class ForgeBiomeRegistry implements BiomeRegistry { + + private static Map biomes = Collections.emptyMap(); + private static Map biomeData = Collections.emptyMap(); + + @Nullable + @Override + public BaseBiome createFromId(int id) { + return new BaseBiome(id); + } + + @Override + public List getBiomes() { + List list = new ArrayList(); + for (int biome : biomes.keySet()) { + list.add(new BaseBiome(biome)); + } + return list; + } + + @Nullable + @Override + public BiomeData getData(BaseBiome biome) { + return biomeData.get(biome.getId()); + } + + /** + * Populate the internal static list of biomes. + * + *

If called repeatedly, the last call will overwrite all previous + * calls.

+ */ + static void populate() { + Map biomes = HashBiMap.create(); + Map biomeData = new HashMap(); + + for (BiomeGenBase biome : BiomeGenBase.biomeList) { + if ((biome == null) || (biomes.containsValue(biome))) { + continue; + } + biomes.put(biome.biomeID, biome); + biomeData.put(biome.biomeID, new ForgeBiomeData(biome)); + } + + ForgeBiomeRegistry.biomes = biomes; + ForgeBiomeRegistry.biomeData = biomeData; + } + + /** + * Cached biome data information. + */ + private static class ForgeBiomeData implements BiomeData { + private final BiomeGenBase biome; + + /** + * Create a new instance. + * + * @param biome the base biome + */ + private ForgeBiomeData(BiomeGenBase biome) { + this.biome = biome; + } + + @Override + public String getName() { + return biome.biomeName; + } + } + +} \ No newline at end of file diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgeBiomeTypes.java b/src/forge/java/com/sk89q/worldedit/forge/ForgeBiomeTypes.java deleted file mode 100644 index 68275e49d..000000000 --- a/src/forge/java/com/sk89q/worldedit/forge/ForgeBiomeTypes.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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 Lesser 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 Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.forge; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; - -import net.minecraft.world.biome.BiomeGenBase; - -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; -import com.sk89q.worldedit.BiomeType; -import com.sk89q.worldedit.BiomeTypes; -import com.sk89q.worldedit.UnknownBiomeTypeException; - -public class ForgeBiomeTypes implements BiomeTypes { - private static BiMap biomes = HashBiMap.create(); - - public ForgeBiomeTypes() { - all(); - } - - public boolean has(String name) { - for (BiomeGenBase biome : BiomeGenBase.biomeList) { - if ((biome != null) && (biome.biomeName.equalsIgnoreCase(name))) { - return true; - } - } - return false; - } - - public BiomeType get(String name) throws UnknownBiomeTypeException { - if (biomes == null) { - all(); - } - Iterator it = biomes.keySet().iterator(); - while (it.hasNext()) { - BiomeType test = (BiomeType) it.next(); - if (test.getName().equalsIgnoreCase(name)) { - return test; - } - } - throw new UnknownBiomeTypeException(name); - } - - public List all() { - if (biomes.isEmpty()) { - biomes = HashBiMap.create(new HashMap()); - for (BiomeGenBase biome : BiomeGenBase.biomeList) { - if ((biome == null) || (biomes.containsValue(biome))) { - continue; - } - biomes.put(new ForgeBiomeType(biome), biome); - } - } - List retBiomes = new ArrayList(); - retBiomes.addAll(biomes.keySet()); - return retBiomes; - } - - public static BiomeType getFromBaseBiome(BiomeGenBase biome) { - return biomes.containsValue(biome) ? (BiomeType) biomes.inverse().get(biome) : BiomeType.UNKNOWN; - } - - public static BiomeGenBase getFromBiomeType(BiomeType biome) { - return (BiomeGenBase) biomes.get(biome); - } -} \ No newline at end of file diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgePlatform.java b/src/forge/java/com/sk89q/worldedit/forge/ForgePlatform.java index 62c04afb3..3f4f9b19b 100644 --- a/src/forge/java/com/sk89q/worldedit/forge/ForgePlatform.java +++ b/src/forge/java/com/sk89q/worldedit/forge/ForgePlatform.java @@ -19,7 +19,7 @@ package com.sk89q.worldedit.forge; -import com.sk89q.worldedit.BiomeTypes; +import com.sk89q.worldedit.world.registry.BiomeRegistry; import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.ServerInterface; import com.sk89q.worldedit.entity.Player; @@ -56,13 +56,13 @@ class ForgePlatform extends ServerInterface implements MultiUserPlatform { private final ForgeWorldEdit mod; private final MinecraftServer server; - private final ForgeBiomeTypes biomes; + private final ForgeBiomeRegistry biomes; private boolean hookingEvents = false; ForgePlatform(ForgeWorldEdit mod) { this.mod = mod; this.server = FMLCommonHandler.instance().getMinecraftServerInstance(); - this.biomes = new ForgeBiomeTypes(); + this.biomes = new ForgeBiomeRegistry(); } boolean isHookingEvents() { @@ -95,11 +95,6 @@ class ForgePlatform extends ServerInterface implements MultiUserPlatform { public void reload() { } - @Override - public BiomeTypes getBiomes() { - return this.biomes; - } - @Override public int schedule(long delay, long period, Runnable task) { return -1; diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgeWorld.java b/src/forge/java/com/sk89q/worldedit/forge/ForgeWorld.java index ac63f7818..fdab7bcf1 100644 --- a/src/forge/java/com/sk89q/worldedit/forge/ForgeWorld.java +++ b/src/forge/java/com/sk89q/worldedit/forge/ForgeWorld.java @@ -20,7 +20,6 @@ package com.sk89q.worldedit.forge; import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.BiomeType; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; @@ -36,7 +35,7 @@ import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.TreeGenerator.TreeType; import com.sk89q.worldedit.world.AbstractWorld; -import com.sk89q.worldedit.world.registry.LegacyWorldData; +import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.registry.WorldData; import net.minecraft.block.Block; import net.minecraft.entity.EntityList; @@ -181,22 +180,23 @@ public class ForgeWorld extends AbstractWorld { } @Override - public BiomeType getBiome(Vector2D position) { + public BaseBiome getBiome(Vector2D position) { checkNotNull(position); - return ForgeBiomeTypes.getFromBaseBiome(getWorld().getBiomeGenForCoords(position.getBlockX(), position.getBlockZ())); + return new BaseBiome(getWorld().getBiomeGenForCoords(position.getBlockX(), position.getBlockZ()).biomeID); } @Override - public void setBiome(Vector2D position, BiomeType biome) { + public boolean setBiome(Vector2D position, BaseBiome biome) { checkNotNull(position); checkNotNull(biome); - if (getWorld().getChunkProvider().chunkExists(position.getBlockX(), position.getBlockZ())) { - Chunk chunk = getWorld().getChunkFromBlockCoords(position.getBlockX(), position.getBlockZ()); - if ((chunk != null) && (chunk.isChunkLoaded)) { - chunk.getBiomeArray()[((position.getBlockZ() & 0xF) << 4 | position.getBlockX() & 0xF)] = (byte) ForgeBiomeTypes.getFromBiomeType(biome).biomeID; - } + Chunk chunk = getWorld().getChunkFromBlockCoords(position.getBlockX(), position.getBlockZ()); + if ((chunk != null) && (chunk.isChunkLoaded)) { + chunk.getBiomeArray()[((position.getBlockZ() & 0xF) << 4 | position.getBlockX() & 0xF)] = (byte) biome.getId(); + return true; } + + return false; } @Override @@ -317,7 +317,7 @@ public class ForgeWorld extends AbstractWorld { @Override public WorldData getWorldData() { - return LegacyWorldData.getInstance(); + return ForgeWorldData.getInstance(); } @Override diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgeBiomeType.java b/src/forge/java/com/sk89q/worldedit/forge/ForgeWorldData.java similarity index 56% rename from src/forge/java/com/sk89q/worldedit/forge/ForgeBiomeType.java rename to src/forge/java/com/sk89q/worldedit/forge/ForgeWorldData.java index 5cd816ad7..c6f3d553c 100644 --- a/src/forge/java/com/sk89q/worldedit/forge/ForgeBiomeType.java +++ b/src/forge/java/com/sk89q/worldedit/forge/ForgeWorldData.java @@ -1,36 +1,53 @@ -/* - * 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 Lesser 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 Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.forge; - -import net.minecraft.world.biome.BiomeGenBase; - -import com.sk89q.worldedit.BiomeType; - -public class ForgeBiomeType implements BiomeType { - private BiomeGenBase biome; - - public ForgeBiomeType(BiomeGenBase biome) { - this.biome = biome; - } - - public String getName() { - return this.biome.biomeName; - } -} \ No newline at end of file +/* + * 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 Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.forge; + +import com.sk89q.worldedit.world.registry.BiomeRegistry; +import com.sk89q.worldedit.world.registry.LegacyWorldData; + +/** + * World data for the Forge platform. + */ +class ForgeWorldData extends LegacyWorldData { + + private static final ForgeWorldData INSTANCE = new ForgeWorldData(); + private final BiomeRegistry biomeRegistry = new ForgeBiomeRegistry(); + + /** + * Create a new instance. + */ + ForgeWorldData() { + } + + @Override + public BiomeRegistry getBiomeRegistry() { + return biomeRegistry; + } + + /** + * Get a static instance. + * + * @return an instance + */ + public static ForgeWorldData getInstance() { + return INSTANCE; + } + +} diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java b/src/forge/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java index dbc53eb1d..e6e740533 100644 --- a/src/forge/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java +++ b/src/forge/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java @@ -103,6 +103,8 @@ public class ForgeWorldEdit { WorldEdit.getInstance().getPlatformManager().unregister(platform); } + ForgeBiomeRegistry.populate(); + this.platform = new ForgePlatform(this); WorldEdit.getInstance().getPlatformManager().register(platform); diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java index 10a849a17..f97f002ea 100644 --- a/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/src/main/java/com/sk89q/worldedit/EditSession.java @@ -76,6 +76,7 @@ import com.sk89q.worldedit.util.collection.DoubleArrayList; import com.sk89q.worldedit.util.eventbus.EventBus; import com.sk89q.worldedit.world.NullWorld; import com.sk89q.worldedit.world.World; +import com.sk89q.worldedit.world.biome.BaseBiome; import javax.annotation.Nullable; import java.util.*; @@ -377,6 +378,16 @@ public class EditSession implements Extent { return changeSet.size(); } + @Override + public BaseBiome getBiome(Vector2D position) { + return bypassNone.getBiome(position); + } + + @Override + public boolean setBiome(Vector2D position, BaseBiome biome) { + return bypassNone.setBiome(position, biome); + } + @Override public BaseBlock getLazyBlock(Vector position) { return world.getLazyBlock(position); @@ -2248,7 +2259,7 @@ public class EditSession implements Extent { } // while } - public int makeBiomeShape(final Region region, final Vector zero, final Vector unit, final BiomeType biomeType, final String expressionString, final boolean hollow) throws ExpressionException, MaxChangedBlocksException { + public int makeBiomeShape(final Region region, final Vector zero, final Vector unit, final BaseBiome biomeType, final String expressionString, final boolean hollow) throws ExpressionException, MaxChangedBlocksException { final Vector2D zero2D = zero.toVector2D(); final Vector2D unit2D = unit.toVector2D(); @@ -2261,7 +2272,7 @@ public class EditSession implements Extent { final ArbitraryBiomeShape shape = new ArbitraryBiomeShape(region) { @Override - protected BiomeType getBiome(int x, int z, BiomeType defaultBiomeType) { + protected BaseBiome getBiome(int x, int z, BaseBiome defaultBiomeType) { final Vector2D current = new Vector2D(x, z); environment.setCurrentBlock(current.toVector(0)); final Vector2D scaled = current.subtract(zero2D).divide(unit2D); diff --git a/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java b/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java index a08f70ab3..953168c3b 100644 --- a/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java @@ -23,15 +23,29 @@ import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.Logging; -import com.sk89q.worldedit.*; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.Vector2D; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.entity.Player; -import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.function.FlatRegionFunction; +import com.sk89q.worldedit.function.FlatRegionMaskingFilter; +import com.sk89q.worldedit.function.biome.BiomeReplace; import com.sk89q.worldedit.function.mask.Mask; -import com.sk89q.worldedit.masks.BiomeTypeMask; -import com.sk89q.worldedit.masks.InvertedMask; +import com.sk89q.worldedit.function.mask.Mask2D; +import com.sk89q.worldedit.function.operation.Operations; +import com.sk89q.worldedit.function.visitor.FlatRegionVisitor; +import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.FlatRegion; import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.regions.Regions; +import com.sk89q.worldedit.util.command.binding.Switch; import com.sk89q.worldedit.world.World; +import com.sk89q.worldedit.world.biome.BaseBiome; +import com.sk89q.worldedit.world.biome.BiomeData; +import com.sk89q.worldedit.world.registry.BiomeRegistry; import java.util.HashSet; import java.util.List; @@ -64,7 +78,7 @@ public class BiomeCommands { max = 1 ) @CommandPermissions("worldedit.biome.list") - public void biomeList(Actor actor, CommandContext args) throws WorldEditException { + public void biomeList(Player player, CommandContext args) throws WorldEditException { int page; int offset; int count = 0; @@ -76,16 +90,22 @@ public class BiomeCommands { offset = (page - 1) * 19; } - List biomes = worldEdit.getServer().getBiomes().all(); + BiomeRegistry biomeRegistry = player.getWorld().getWorldData().getBiomeRegistry(); + List biomes = biomeRegistry.getBiomes(); int totalPages = biomes.size() / 19 + 1; - actor.print("Available Biomes (page " + page + "/" + totalPages + ") :"); - for (BiomeType biome : biomes) { + player.print("Available Biomes (page " + page + "/" + totalPages + ") :"); + for (BaseBiome biome : biomes) { if (offset > 0) { offset--; } else { - actor.print(" " + biome.getName()); - if (++count == 19) { - break; + BiomeData data = biomeRegistry.getData(biome); + if (data != null) { + player.print(" " + data.getName()); + if (++count == 19) { + break; + } + } else { + player.print(" "); } } } @@ -103,7 +123,11 @@ public class BiomeCommands { max = 0 ) @CommandPermissions("worldedit.biome.info") - public void biomeInfo(CommandContext args, Player player, LocalSession session) throws WorldEditException { + public void biomeInfo(Player player, LocalSession session, CommandContext args) throws WorldEditException { + BiomeRegistry biomeRegistry = player.getWorld().getWorldData().getBiomeRegistry(); + Set biomes = new HashSet(); + String qualifier; + if (args.hasFlag('t')) { Vector blockPosition = player.getBlockTrace(300); if (blockPosition == null) { @@ -111,15 +135,18 @@ public class BiomeCommands { return; } - BiomeType biome = player.getWorld().getBiome(blockPosition.toVector2D()); - player.print("Biome: " + biome.getName()); + BaseBiome biome = player.getWorld().getBiome(blockPosition.toVector2D()); + biomes.add(biome); + + qualifier = "at line of sight point"; } else if (args.hasFlag('p')) { - BiomeType biome = player.getWorld().getBiome(player.getPosition().toVector2D()); - player.print("Biome: " + biome.getName()); + BaseBiome biome = player.getWorld().getBiome(player.getPosition().toVector2D()); + biomes.add(biome); + + qualifier = "at your position"; } else { World world = player.getWorld(); Region region = session.getSelection(world); - Set biomes = new HashSet(); if (region instanceof FlatRegion) { for (Vector2D pt : ((FlatRegion) region).asFlatRegion()) { @@ -131,9 +158,16 @@ public class BiomeCommands { } } - player.print("Biomes:"); - for (BiomeType biome : biomes) { - player.print(" " + biome.getName()); + qualifier = "in your selection"; + } + + player.print(biomes.size() != 1 ? "Biomes " + qualifier + ":" : "Biome " + qualifier + ":"); + for (BaseBiome biome : biomes) { + BiomeData data = biomeRegistry.getData(biome); + if (data != null) { + player.print(" " + data.getName()); + } else { + player.print(" "); } } } @@ -145,65 +179,31 @@ public class BiomeCommands { desc = "Sets the biome of the player's current block or region.", help = "Set the biome of the region.\n" + - "By default use all the blocks contained in your selection.\n" + - "-p use the block you are currently in", - min = 1, - max = 1 + "By default use all the blocks contained in your selection.\n" + + "-p use the block you are currently in" ) @Logging(REGION) @CommandPermissions("worldedit.biome.set") - public void setBiome(CommandContext args, Player player, LocalSession session, EditSession editSession) throws WorldEditException { - final BiomeType target = worldEdit.getServer().getBiomes().get(args.getString(0)); - if (target == null) { - player.printError("Biome '" + args.getString(0) + "' does not exist!"); - return; - } - + public void setBiome(Player player, LocalSession session, EditSession editSession, BaseBiome target, @Switch('p') boolean atPosition) throws WorldEditException { + World world = player.getWorld(); + Region region; Mask mask = editSession.getMask(); - BiomeTypeMask biomeMask = null; - boolean inverted = false; - if (mask instanceof BiomeTypeMask) { - biomeMask = (BiomeTypeMask) mask; - } else if (mask instanceof InvertedMask && ((InvertedMask) mask).getInvertedMask() instanceof BiomeTypeMask) { - inverted = true; - biomeMask = (BiomeTypeMask) ((InvertedMask) mask).getInvertedMask(); - } + Mask2D mask2d = mask != null ? mask.toMask2D() : null; - if (args.hasFlag('p')) { - Vector2D pos = player.getPosition().toVector2D(); - if (biomeMask == null || (biomeMask.matches2D(editSession, pos) ^ inverted)) { - player.getWorld().setBiome(pos, target); - player.print("Biome changed to " + target.getName() + " at your current location."); - } else { - player.print("Your global mask doesn't match this biome. Type //gmask to disable it."); - } + if (atPosition) { + region = new CuboidRegion(player.getPosition(), player.getPosition()); } else { - int affected = 0; - World world = player.getWorld(); - Region region = session.getSelection(world); - - if (region instanceof FlatRegion) { - for (Vector2D pt : ((FlatRegion) region).asFlatRegion()) { - if (biomeMask == null || (biomeMask.matches2D(editSession, pt) ^ inverted)) { - world.setBiome(pt, target); - ++affected; - } - } - } else { - HashSet alreadyVisited = new HashSet(); - for (Vector pt : region) { - if (!alreadyVisited.contains((long)pt.getBlockX() << 32 | pt.getBlockZ())) { - alreadyVisited.add(((long)pt.getBlockX() << 32 | pt.getBlockZ())); - if (biomeMask == null || (biomeMask.matches(editSession, pt) ^ inverted)) { - world.setBiome(pt.toVector2D(), target); - ++affected; - } - } - } - } - - player.print("Biome changed to " + target.getName() + ". " + affected + " columns affected."); + region = session.getSelection(world); } + + FlatRegionFunction replace = new BiomeReplace(editSession, target); + if (mask2d != null) { + replace = new FlatRegionMaskingFilter(mask2d, replace); + } + FlatRegionVisitor visitor = new FlatRegionVisitor(Regions.asFlatRegion(region), replace); + Operations.completeLegacy(visitor); + + player.print("Biomes were changed in " + visitor.getAffected() + " columns. You may have to rejoin your game (or close and reopen your world) to see a change."); } } diff --git a/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java b/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java index ffce9f7ec..09abf3b99 100644 --- a/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java @@ -22,7 +22,11 @@ package com.sk89q.worldedit.command; import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.Logging; -import com.sk89q.worldedit.*; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Patterns; @@ -35,6 +39,7 @@ import com.sk89q.worldedit.util.command.binding.Range; import com.sk89q.worldedit.util.command.binding.Switch; import com.sk89q.worldedit.util.command.binding.Text; import com.sk89q.worldedit.util.command.parametric.Optional; +import com.sk89q.worldedit.world.biome.BaseBiome; import static com.google.common.base.Preconditions.checkNotNull; import static com.sk89q.minecraft.util.commands.Logging.LogMode.*; @@ -332,7 +337,7 @@ public class GenerationCommands { @Logging(ALL) public void generateBiome(Player player, LocalSession session, EditSession editSession, @Selection Region region, - BiomeType target, + BaseBiome target, @Text String expression, @Switch('h') boolean hollow, @Switch('r') boolean useRawCoords, @@ -368,7 +373,7 @@ public class GenerationCommands { try { final int affected = editSession.makeBiomeShape(region, zero, unit, target, expression, hollow); player.findFreePosition(); - player.print("Biome changed to " + target.getName() + ". " + affected + " columns affected."); + player.print("" + affected + " columns affected."); } catch (ExpressionException e) { player.printError(e.getMessage()); } diff --git a/src/main/java/com/sk89q/worldedit/extension/factory/DefaultMaskParser.java b/src/main/java/com/sk89q/worldedit/extension/factory/DefaultMaskParser.java index 9b6dfdf94..2d697fbbb 100644 --- a/src/main/java/com/sk89q/worldedit/extension/factory/DefaultMaskParser.java +++ b/src/main/java/com/sk89q/worldedit/extension/factory/DefaultMaskParser.java @@ -19,17 +19,30 @@ package com.sk89q.worldedit.extension.factory; -import com.sk89q.worldedit.*; +import com.sk89q.worldedit.IncompleteRegionException; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.NoMatchException; import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.function.mask.*; +import com.sk89q.worldedit.function.mask.BiomeMask2D; +import com.sk89q.worldedit.function.mask.BlockMask; +import com.sk89q.worldedit.function.mask.ExistingBlockMask; +import com.sk89q.worldedit.function.mask.Mask; +import com.sk89q.worldedit.function.mask.MaskIntersection; +import com.sk89q.worldedit.function.mask.Masks; +import com.sk89q.worldedit.function.mask.NoiseFilter; +import com.sk89q.worldedit.function.mask.OffsetMask; +import com.sk89q.worldedit.function.mask.RegionMask; +import com.sk89q.worldedit.function.mask.SolidBlockMask; import com.sk89q.worldedit.internal.registry.InputParser; -import com.sk89q.worldedit.masks.BiomeTypeMask; import com.sk89q.worldedit.math.noise.RandomNoise; import com.sk89q.worldedit.session.request.Request; import com.sk89q.worldedit.session.request.RequestSelection; +import com.sk89q.worldedit.world.biome.BaseBiome; +import com.sk89q.worldedit.world.biome.Biomes; +import com.sk89q.worldedit.world.registry.BiomeRegistry; import java.util.ArrayList; import java.util.HashSet; @@ -109,18 +122,19 @@ class DefaultMaskParser extends InputParser { return new MaskIntersection(offsetMask, Masks.negate(submask)); case '$': - Set biomes = new HashSet(); + Set biomes = new HashSet(); String[] biomesList = component.substring(1).split(","); + BiomeRegistry biomeRegistry = context.requireWorld().getWorldData().getBiomeRegistry(); + List knownBiomes = biomeRegistry.getBiomes(); for (String biomeName : biomesList) { - try { - BiomeType biome = worldEdit.getServer().getBiomes().get(biomeName); - biomes.add(biome); - } catch (UnknownBiomeTypeException e) { + BaseBiome biome = Biomes.findBiomeByName(knownBiomes, biomeName, biomeRegistry); + if (biome == null) { throw new InputParseException("Unknown biome '" + biomeName + "'"); } + biomes.add(biome); } - return Masks.wrap(new BiomeTypeMask(biomes)); + return Masks.asMask(new BiomeMask2D(context.requireExtent(), biomes)); case '%': int i = Integer.parseInt(component.substring(1)); diff --git a/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java b/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java index bc90eaa5d..412afd9ea 100644 --- a/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java +++ b/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java @@ -19,7 +19,6 @@ package com.sk89q.worldedit.extension.platform; -import com.sk89q.worldedit.BiomeTypes; import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.util.command.Dispatcher; @@ -58,13 +57,6 @@ public interface Platform { */ void reload(); - /** - * Returns all available biomes. - * - * @return an object containing all the biomes - */ - 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/extent/AbstractDelegateExtent.java b/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java index 65399bbf4..7a1bd25f9 100644 --- a/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java +++ b/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java @@ -20,6 +20,7 @@ package com.sk89q.worldedit.extent; import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.entity.BaseEntity; @@ -28,6 +29,7 @@ import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.OperationQueue; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.world.biome.BaseBiome; import javax.annotation.Nullable; @@ -92,6 +94,16 @@ public abstract class AbstractDelegateExtent implements Extent { return extent.getEntities(region); } + @Override + public BaseBiome getBiome(Vector2D position) { + return extent.getBiome(position); + } + + @Override + public boolean setBiome(Vector2D position, BaseBiome biome) { + return extent.setBiome(position, biome); + } + @Override public Vector getMinimumPoint() { return extent.getMinimumPoint(); diff --git a/src/main/java/com/sk89q/worldedit/extent/InputExtent.java b/src/main/java/com/sk89q/worldedit/extent/InputExtent.java index f40750720..81fcce5c9 100644 --- a/src/main/java/com/sk89q/worldedit/extent/InputExtent.java +++ b/src/main/java/com/sk89q/worldedit/extent/InputExtent.java @@ -20,9 +20,10 @@ package com.sk89q.worldedit.extent; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.function.pattern.Pattern; +import com.sk89q.worldedit.world.biome.BaseBiome; /** * Provides the current state of blocks, entities, and so on. @@ -74,4 +75,15 @@ public interface InputExtent { */ BaseBlock getLazyBlock(Vector position); + /** + * Get the biome at the given location. + * + *

If there is no biome available, then the ocean biome should be + * returned.

+ * + * @param position the (x, z) location to check the biome at + * @return the biome at the location + */ + BaseBiome getBiome(Vector2D position); + } diff --git a/src/main/java/com/sk89q/worldedit/extent/NullExtent.java b/src/main/java/com/sk89q/worldedit/extent/NullExtent.java index 3df4879de..1979bdaaf 100644 --- a/src/main/java/com/sk89q/worldedit/extent/NullExtent.java +++ b/src/main/java/com/sk89q/worldedit/extent/NullExtent.java @@ -20,6 +20,7 @@ package com.sk89q.worldedit.extent; import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.entity.BaseEntity; @@ -27,6 +28,7 @@ import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.world.biome.BaseBiome; import javax.annotation.Nullable; import java.util.Collections; @@ -76,11 +78,22 @@ public class NullExtent implements Extent { return new BaseBlock(0); } + @Nullable + @Override + public BaseBiome getBiome(Vector2D position) { + return null; + } + @Override public boolean setBlock(Vector position, BaseBlock block) throws WorldEditException { return false; } + @Override + public boolean setBiome(Vector2D position, BaseBiome biome) { + return false; + } + @Nullable @Override public Operation commit() { diff --git a/src/main/java/com/sk89q/worldedit/extent/OutputExtent.java b/src/main/java/com/sk89q/worldedit/extent/OutputExtent.java index 1468982f2..e0268495d 100644 --- a/src/main/java/com/sk89q/worldedit/extent/OutputExtent.java +++ b/src/main/java/com/sk89q/worldedit/extent/OutputExtent.java @@ -20,9 +20,11 @@ package com.sk89q.worldedit.extent; import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.function.operation.Operation; +import com.sk89q.worldedit.world.biome.BaseBiome; import javax.annotation.Nullable; @@ -49,6 +51,15 @@ public interface OutputExtent { */ boolean setBlock(Vector position, BaseBlock block) throws WorldEditException; + /** + * Set the biome. + * + * @param position the (x, z) location to set the biome at + * @param biome the biome to set to + * @return true if the biome was successfully set (return value may not be accurate) + */ + boolean setBiome(Vector2D position, BaseBiome biome); + /** * Return an {@link Operation} that should be called to tie up loose ends * (such as to commit changes in a buffer). diff --git a/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java b/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java index 43fa5597f..1b819e036 100644 --- a/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java +++ b/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java @@ -20,6 +20,7 @@ package com.sk89q.worldedit.extent.clipboard; import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BlockID; @@ -28,6 +29,7 @@ import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.world.biome.BaseBiome; import javax.annotation.Nullable; import java.util.ArrayList; @@ -146,6 +148,16 @@ public class BlockArrayClipboard implements Clipboard { } } + @Override + public BaseBiome getBiome(Vector2D position) { + return new BaseBiome(0); + } + + @Override + public boolean setBiome(Vector2D position, BaseBiome biome) { + return false; + } + @Nullable @Override public Operation commit() { diff --git a/src/main/java/com/sk89q/worldedit/function/biome/BiomeReplace.java b/src/main/java/com/sk89q/worldedit/function/biome/BiomeReplace.java new file mode 100644 index 000000000..f877adce5 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/function/biome/BiomeReplace.java @@ -0,0 +1,56 @@ +/* + * 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 Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.function.biome; + +import com.sk89q.worldedit.Vector2D; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.function.FlatRegionFunction; +import com.sk89q.worldedit.world.biome.BaseBiome; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Replaces the biome at the locations that this function is applied to. + */ +public class BiomeReplace implements FlatRegionFunction { + + private final Extent extent; + private BaseBiome biome; + + /** + * Create a new instance. + * + * @param extent an extent + * @param biome a biome + */ + public BiomeReplace(Extent extent, BaseBiome biome) { + checkNotNull(extent); + checkNotNull(biome); + this.extent = extent; + this.biome = biome; + } + + @Override + public boolean apply(Vector2D position) throws WorldEditException { + return extent.setBiome(position, biome); + } + +} diff --git a/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask2D.java b/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask2D.java new file mode 100644 index 000000000..75240db18 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask2D.java @@ -0,0 +1,98 @@ +/* + * 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 Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.function.mask; + +import com.sk89q.worldedit.Vector2D; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.world.biome.BaseBiome; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Tests true if the biome at applied points is the same as the one given. + */ +public class BiomeMask2D extends AbstractMask2D { + + private final Extent extent; + private final Set biomes = new HashSet(); + + /** + * Create a new biome mask. + * + * @param extent the extent + * @param biomes a list of biomes to match + */ + public BiomeMask2D(Extent extent, Collection biomes) { + checkNotNull(extent); + checkNotNull(biomes); + this.extent = extent; + this.biomes.addAll(biomes); + } + + /** + * Create a new biome mask. + * + * @param extent the extent + * @param biome an array of biomes to match + */ + public BiomeMask2D(Extent extent, BaseBiome... biome) { + this(extent, Arrays.asList(checkNotNull(biome))); + } + + /** + * Add the given biomes to the list of criteria. + * + * @param biomes a list of biomes + */ + public void add(Collection biomes) { + checkNotNull(biomes); + this.biomes.addAll(biomes); + } + + /** + * Add the given biomes to the list of criteria. + * + * @param biome an array of biomes + */ + public void add(BaseBiome... biome) { + add(Arrays.asList(checkNotNull(biome))); + } + + /** + * Get the list of biomes that are tested with. + * + * @return a list of biomes + */ + public Collection getBiomes() { + return biomes; + } + + @Override + public boolean test(Vector2D vector) { + BaseBiome biome = extent.getBiome(vector); + return biomes.contains(biome); + } + +} diff --git a/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java b/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java index e05532438..91ac89c14 100644 --- a/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java +++ b/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java @@ -23,6 +23,7 @@ import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.BaseBlock; +import javax.annotation.Nullable; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; @@ -96,4 +97,11 @@ public class BlockMask extends AbstractExtentMask { BaseBlock block = getExtent().getBlock(vector); return blocks.contains(block) || blocks.contains(new BaseBlock(block.getType(), -1)); } + + @Nullable + @Override + public Mask2D toMask2D() { + return null; + } + } diff --git a/src/main/java/com/sk89q/worldedit/function/mask/BoundedHeightMask.java b/src/main/java/com/sk89q/worldedit/function/mask/BoundedHeightMask.java index 81d143c3d..fe35ff1ef 100644 --- a/src/main/java/com/sk89q/worldedit/function/mask/BoundedHeightMask.java +++ b/src/main/java/com/sk89q/worldedit/function/mask/BoundedHeightMask.java @@ -21,6 +21,8 @@ package com.sk89q.worldedit.function.mask; import com.sk89q.worldedit.Vector; +import javax.annotation.Nullable; + import static com.google.common.base.Preconditions.checkArgument; /** @@ -49,4 +51,10 @@ public class BoundedHeightMask extends AbstractMask { return vector.getY() >= minY && vector.getY() <= maxY; } + @Nullable + @Override + public Mask2D toMask2D() { + return null; + } + } diff --git a/src/main/java/com/sk89q/worldedit/function/mask/ExistingBlockMask.java b/src/main/java/com/sk89q/worldedit/function/mask/ExistingBlockMask.java index 80e9719fc..c3d8f1037 100644 --- a/src/main/java/com/sk89q/worldedit/function/mask/ExistingBlockMask.java +++ b/src/main/java/com/sk89q/worldedit/function/mask/ExistingBlockMask.java @@ -23,6 +23,8 @@ import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.BlockID; +import javax.annotation.Nullable; + /** * A mask that returns true whenever the block at the location is not * an air block (it contains some other block). @@ -43,4 +45,10 @@ public class ExistingBlockMask extends AbstractExtentMask { return getExtent().getLazyBlock(vector).getType() != BlockID.AIR; } + @Nullable + @Override + public Mask2D toMask2D() { + return null; + } + } diff --git a/src/main/java/com/sk89q/worldedit/function/mask/Mask.java b/src/main/java/com/sk89q/worldedit/function/mask/Mask.java index 611b1b662..96b4af82b 100644 --- a/src/main/java/com/sk89q/worldedit/function/mask/Mask.java +++ b/src/main/java/com/sk89q/worldedit/function/mask/Mask.java @@ -21,6 +21,8 @@ package com.sk89q.worldedit.function.mask; import com.sk89q.worldedit.Vector; +import javax.annotation.Nullable; + /** * Tests whether a given vector meets a criteria. */ @@ -34,4 +36,12 @@ public interface Mask { */ boolean test(Vector vector); + /** + * Get the 2D version of this mask if one exists. + * + * @return a 2D mask version or {@code null} if this mask can't be 2D + */ + @Nullable + Mask2D toMask2D(); + } diff --git a/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java b/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java index d1a600ef4..d98fdadac 100644 --- a/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java +++ b/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java @@ -21,9 +21,12 @@ package com.sk89q.worldedit.function.mask; import com.sk89q.worldedit.Vector; +import javax.annotation.Nullable; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; +import java.util.List; import java.util.Set; import static com.google.common.base.Preconditions.checkNotNull; @@ -86,7 +89,7 @@ public class MaskIntersection extends AbstractMask { @Override public boolean test(Vector vector) { - if (masks.size() == 0) { + if (masks.isEmpty()) { return false; } @@ -99,4 +102,19 @@ public class MaskIntersection extends AbstractMask { return true; } + @Nullable + @Override + public Mask2D toMask2D() { + List mask2dList = new ArrayList(); + for (Mask mask : masks) { + Mask2D mask2d = mask.toMask2D(); + if (mask2d != null) { + mask2dList.add(mask2d); + } else { + return null; + } + } + return new MaskIntersection2D(mask2dList); + } + } diff --git a/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection2D.java b/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection2D.java new file mode 100644 index 000000000..02e605ff9 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection2D.java @@ -0,0 +1,100 @@ +/* + * 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 Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.function.mask; + +import com.sk89q.worldedit.Vector2D; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Tests true if all contained masks test true. + */ +public class MaskIntersection2D implements Mask2D { + + private final Set masks = new HashSet(); + + /** + * Create a new intersection. + * + * @param masks a list of masks + */ + public MaskIntersection2D(Collection masks) { + checkNotNull(masks); + this.masks.addAll(masks); + } + + /** + * Create a new intersection. + * + * @param mask a list of masks + */ + public MaskIntersection2D(Mask2D... mask) { + this(Arrays.asList(checkNotNull(mask))); + } + + /** + * Add some masks to the list. + * + * @param masks the masks + */ + public void add(Collection masks) { + checkNotNull(masks); + this.masks.addAll(masks); + } + + /** + * Add some masks to the list. + * + * @param mask the masks + */ + public void add(Mask2D... mask) { + add(Arrays.asList(checkNotNull(mask))); + } + + /** + * Get the masks that are tested with. + * + * @return the masks + */ + public Collection getMasks() { + return masks; + } + + @Override + public boolean test(Vector2D vector) { + if (masks.isEmpty()) { + return false; + } + + for (Mask2D mask : masks) { + if (!mask.test(vector)) { + return false; + } + } + + return true; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/function/mask/MaskUnion.java b/src/main/java/com/sk89q/worldedit/function/mask/MaskUnion.java index a02983f4a..955ab779e 100644 --- a/src/main/java/com/sk89q/worldedit/function/mask/MaskUnion.java +++ b/src/main/java/com/sk89q/worldedit/function/mask/MaskUnion.java @@ -21,7 +21,10 @@ package com.sk89q.worldedit.function.mask; import com.sk89q.worldedit.Vector; +import javax.annotation.Nullable; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; /** * Combines several masks and requires that one or more masks return true @@ -61,4 +64,18 @@ public class MaskUnion extends MaskIntersection { return false; } + @Nullable + @Override + public Mask2D toMask2D() { + List mask2dList = new ArrayList(); + for (Mask mask : getMasks()) { + Mask2D mask2d = mask.toMask2D(); + if (mask2d != null) { + mask2dList.add(mask2d); + } else { + return null; + } + } + return new MaskUnion2D(mask2dList); + } } diff --git a/src/legacy/java/com/sk89q/worldedit/masks/BiomeTypeMask.java b/src/main/java/com/sk89q/worldedit/function/mask/MaskUnion2D.java similarity index 54% rename from src/legacy/java/com/sk89q/worldedit/masks/BiomeTypeMask.java rename to src/main/java/com/sk89q/worldedit/function/mask/MaskUnion2D.java index 97ed58e09..099dc9a05 100644 --- a/src/legacy/java/com/sk89q/worldedit/masks/BiomeTypeMask.java +++ b/src/main/java/com/sk89q/worldedit/function/mask/MaskUnion2D.java @@ -17,34 +17,46 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.masks; +package com.sk89q.worldedit.function.mask; -import java.util.HashSet; -import java.util.Set; - -import com.sk89q.worldedit.BiomeType; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; -public class BiomeTypeMask extends AbstractMask { - private final Set biomes; +import java.util.Collection; - public BiomeTypeMask() { - this(new HashSet()); +/** + * Tests true if any contained mask is true, even if it just one. + */ +public class MaskUnion2D extends MaskIntersection2D { + + /** + * Create a new union. + * + * @param masks a list of masks + */ + public MaskUnion2D(Collection masks) { + super(masks); } - public BiomeTypeMask(Set biomes) { - this.biomes = biomes; - } - - public boolean matches2D(EditSession editSession, Vector2D pos) { - BiomeType biome = editSession.getWorld().getBiome(pos); - return biomes.contains(biome); + /** + * Create a new union. + * + * @param mask a list of masks + */ + public MaskUnion2D(Mask2D... mask) { + super(mask); } @Override - public boolean matches(EditSession editSession, Vector pos) { - return matches2D(editSession, pos.toVector2D()); + public boolean test(Vector2D vector) { + Collection masks = getMasks(); + + for (Mask2D mask : masks) { + if (mask.test(vector)) { + return true; + } + } + + return false; } + } diff --git a/src/main/java/com/sk89q/worldedit/function/mask/Masks.java b/src/main/java/com/sk89q/worldedit/function/mask/Masks.java index 689b127a7..837bcd2ae 100644 --- a/src/main/java/com/sk89q/worldedit/function/mask/Masks.java +++ b/src/main/java/com/sk89q/worldedit/function/mask/Masks.java @@ -22,6 +22,8 @@ package com.sk89q.worldedit.function.mask; import com.sk89q.worldedit.*; import com.sk89q.worldedit.session.request.Request; +import javax.annotation.Nullable; + import static com.google.common.base.Preconditions.checkNotNull; /** @@ -29,6 +31,9 @@ import static com.google.common.base.Preconditions.checkNotNull; */ public final class Masks { + private static final AlwaysTrue ALWAYS_TRUE = new AlwaysTrue(); + private static final AlwaysFalse ALWAYS_FALSE = new AlwaysFalse(); + private Masks() { } @@ -38,12 +43,7 @@ public final class Masks { * @return a mask */ public static Mask alwaysTrue() { - return new AbstractMask() { - @Override - public boolean test(Vector vector) { - return true; - } - }; + return ALWAYS_TRUE; } /** @@ -52,12 +52,7 @@ public final class Masks { * @return a mask */ public static Mask2D alwaysTrue2D() { - return new AbstractMask2D() { - @Override - public boolean test(Vector2D vector) { - return true; - } - }; + return ALWAYS_TRUE; } /** @@ -67,12 +62,29 @@ public final class Masks { * @return a new mask */ public static Mask negate(final Mask mask) { + if (mask instanceof AlwaysTrue) { + return ALWAYS_FALSE; + } else if (mask instanceof AlwaysFalse) { + return ALWAYS_TRUE; + } + checkNotNull(mask); return new AbstractMask() { @Override public boolean test(Vector vector) { return !mask.test(vector); } + + @Nullable + @Override + public Mask2D toMask2D() { + Mask2D mask2d = mask.toMask2D(); + if (mask2d != null) { + return negate(mask2d); + } else { + return null; + } + } }; } @@ -83,6 +95,12 @@ public final class Masks { * @return a new mask */ public static Mask2D negate(final Mask2D mask) { + if (mask instanceof AlwaysTrue) { + return ALWAYS_FALSE; + } else if (mask instanceof AlwaysFalse) { + return ALWAYS_TRUE; + } + checkNotNull(mask); return new AbstractMask2D() { @Override @@ -92,6 +110,27 @@ public final class Masks { }; } + /** + * Return a 3-dimensional version of a 2D mask. + * + * @param mask the mask to make 3D + * @return a 3D mask + */ + public static Mask asMask(final Mask2D mask) { + return new AbstractMask() { + @Override + public boolean test(Vector vector) { + return mask.test(vector.toVector2D()); + } + + @Nullable + @Override + public Mask2D toMask2D() { + return mask; + } + }; + } + /** * Wrap an old-style mask and convert it to a new mask. *

@@ -113,6 +152,12 @@ public final class Masks { public boolean test(Vector vector) { return mask.matches(editSession, vector); } + + @Nullable + @Override + public Mask2D toMask2D() { + return null; + } }; } @@ -135,6 +180,12 @@ public final class Masks { EditSession editSession = Request.request().getEditSession(); return editSession != null && mask.matches(editSession, vector); } + + @Nullable + @Override + public Mask2D toMask2D() { + return null; + } }; } @@ -156,4 +207,40 @@ public final class Masks { }; } + private static class AlwaysTrue implements Mask, Mask2D { + @Override + public boolean test(Vector vector) { + return true; + } + + @Override + public boolean test(Vector2D vector) { + return true; + } + + @Nullable + @Override + public Mask2D toMask2D() { + return this; + } + } + + private static class AlwaysFalse implements Mask, Mask2D { + @Override + public boolean test(Vector vector) { + return false; + } + + @Override + public boolean test(Vector2D vector) { + return false; + } + + @Nullable + @Override + public Mask2D toMask2D() { + return this; + } + } + } diff --git a/src/main/java/com/sk89q/worldedit/function/mask/NoiseFilter.java b/src/main/java/com/sk89q/worldedit/function/mask/NoiseFilter.java index f5aa09807..7c5b658d4 100644 --- a/src/main/java/com/sk89q/worldedit/function/mask/NoiseFilter.java +++ b/src/main/java/com/sk89q/worldedit/function/mask/NoiseFilter.java @@ -22,6 +22,8 @@ package com.sk89q.worldedit.function.mask; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.math.noise.NoiseGenerator; +import javax.annotation.Nullable; + import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; @@ -89,4 +91,10 @@ public class NoiseFilter extends AbstractMask { return noiseGenerator.noise(vector) <= density; } + @Nullable + @Override + public Mask2D toMask2D() { + return new NoiseFilter2D(getNoiseGenerator(), getDensity()); + } + } diff --git a/src/main/java/com/sk89q/worldedit/function/mask/OffsetMask.java b/src/main/java/com/sk89q/worldedit/function/mask/OffsetMask.java index 833a543ef..b5358cb30 100644 --- a/src/main/java/com/sk89q/worldedit/function/mask/OffsetMask.java +++ b/src/main/java/com/sk89q/worldedit/function/mask/OffsetMask.java @@ -21,10 +21,13 @@ package com.sk89q.worldedit.function.mask; import com.sk89q.worldedit.Vector; +import javax.annotation.Nullable; + import static com.google.common.base.Preconditions.checkNotNull; /** - * Checks whether the provided mask tests true for an offset position. + * Checks whether another mask tests true for a position that is offset + * a given vector. */ public class OffsetMask extends AbstractMask { @@ -87,4 +90,15 @@ public class OffsetMask extends AbstractMask { return getMask().test(vector.add(offset)); } + @Nullable + @Override + public Mask2D toMask2D() { + Mask2D childMask = getMask().toMask2D(); + if (childMask != null) { + return new OffsetMask2D(childMask, getOffset().toVector2D()); + } else { + return null; + } + } + } diff --git a/src/main/java/com/sk89q/worldedit/function/mask/OffsetMask2D.java b/src/main/java/com/sk89q/worldedit/function/mask/OffsetMask2D.java new file mode 100644 index 000000000..50d2835ba --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/function/mask/OffsetMask2D.java @@ -0,0 +1,91 @@ +/* + * 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 Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.function.mask; + +import com.sk89q.worldedit.Vector2D; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Checks whether another mask tests true for a position that is offset + * a given vector. + */ +public class OffsetMask2D extends AbstractMask2D { + + private Mask2D mask; + private Vector2D offset; + + /** + * Create a new instance. + * + * @param mask the mask + * @param offset the offset + */ + public OffsetMask2D(Mask2D mask, Vector2D offset) { + checkNotNull(mask); + checkNotNull(offset); + this.mask = mask; + this.offset = offset; + } + + /** + * Get the mask. + * + * @return the mask + */ + public Mask2D getMask() { + return mask; + } + + /** + * Set the mask. + * + * @param mask the mask + */ + public void setMask(Mask2D mask) { + checkNotNull(mask); + this.mask = mask; + } + + /** + * Get the offset. + * + * @return the offset + */ + public Vector2D getOffset() { + return offset; + } + + /** + * Set the offset. + * + * @param offset the offset + */ + public void setOffset(Vector2D offset) { + checkNotNull(offset); + this.offset = offset; + } + + @Override + public boolean test(Vector2D vector) { + return getMask().test(vector.add(offset)); + } + +} diff --git a/src/main/java/com/sk89q/worldedit/function/mask/RegionMask.java b/src/main/java/com/sk89q/worldedit/function/mask/RegionMask.java index 04e1c4dc3..1ddf891fe 100644 --- a/src/main/java/com/sk89q/worldedit/function/mask/RegionMask.java +++ b/src/main/java/com/sk89q/worldedit/function/mask/RegionMask.java @@ -22,6 +22,8 @@ package com.sk89q.worldedit.function.mask; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.regions.Region; +import javax.annotation.Nullable; + import static com.google.common.base.Preconditions.checkNotNull; /** @@ -64,4 +66,10 @@ public class RegionMask extends AbstractMask { return region.contains(vector); } + @Nullable + @Override + public Mask2D toMask2D() { + return null; + } + } diff --git a/src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java b/src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java index 2428643c2..b6a10972a 100644 --- a/src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java +++ b/src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java @@ -24,6 +24,8 @@ import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.BlockType; +import javax.annotation.Nullable; + public class SolidBlockMask extends AbstractExtentMask { public SolidBlockMask(Extent extent) { @@ -37,4 +39,10 @@ public class SolidBlockMask extends AbstractExtentMask { return !BlockType.canPassThrough(lazyBlock.getType(), lazyBlock.getData()); } + @Nullable + @Override + public Mask2D toMask2D() { + return null; + } + } diff --git a/src/main/java/com/sk89q/worldedit/internal/LocalWorldAdapter.java b/src/main/java/com/sk89q/worldedit/internal/LocalWorldAdapter.java index 2e5ab5c5d..d800de00a 100644 --- a/src/main/java/com/sk89q/worldedit/internal/LocalWorldAdapter.java +++ b/src/main/java/com/sk89q/worldedit/internal/LocalWorldAdapter.java @@ -19,7 +19,6 @@ package com.sk89q.worldedit.internal; -import com.sk89q.worldedit.BiomeType; import com.sk89q.worldedit.BlockVector2D; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalWorld; @@ -37,6 +36,7 @@ import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.TreeGenerator.TreeType; import com.sk89q.worldedit.world.World; +import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.registry.WorldData; import javax.annotation.Nullable; @@ -109,13 +109,13 @@ public class LocalWorldAdapter extends LocalWorld { } @Override - public BiomeType getBiome(Vector2D position) { + public BaseBiome getBiome(Vector2D position) { return world.getBiome(position); } @Override - public void setBiome(Vector2D position, BiomeType biome) { - world.setBiome(position, biome); + public boolean setBiome(Vector2D position, BaseBiome biome) { + return world.setBiome(position, biome); } @Override diff --git a/src/main/java/com/sk89q/worldedit/internal/ServerInterfaceAdapter.java b/src/main/java/com/sk89q/worldedit/internal/ServerInterfaceAdapter.java index 16d86ee5e..32d0922cc 100644 --- a/src/main/java/com/sk89q/worldedit/internal/ServerInterfaceAdapter.java +++ b/src/main/java/com/sk89q/worldedit/internal/ServerInterfaceAdapter.java @@ -19,7 +19,6 @@ package com.sk89q.worldedit.internal; -import com.sk89q.worldedit.BiomeTypes; import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.ServerInterface; import com.sk89q.worldedit.entity.Player; @@ -67,11 +66,6 @@ public class ServerInterfaceAdapter extends ServerInterface { platform.reload(); } - @Override - public BiomeTypes getBiomes() { - return platform.getBiomes(); - } - @Override public int schedule(long delay, long period, Runnable task) { return platform.schedule(delay, period, task); diff --git a/src/main/java/com/sk89q/worldedit/internal/command/WorldEditBinding.java b/src/main/java/com/sk89q/worldedit/internal/command/WorldEditBinding.java index 7a6aa4ad3..fbccb8204 100644 --- a/src/main/java/com/sk89q/worldedit/internal/command/WorldEditBinding.java +++ b/src/main/java/com/sk89q/worldedit/internal/command/WorldEditBinding.java @@ -19,7 +19,6 @@ package com.sk89q.worldedit.internal.command; -import com.sk89q.worldedit.BiomeType; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.IncompleteRegionException; import com.sk89q.worldedit.LocalSession; @@ -47,8 +46,12 @@ import com.sk89q.worldedit.util.command.parametric.BindingHelper; import com.sk89q.worldedit.util.command.parametric.BindingMatch; import com.sk89q.worldedit.util.command.parametric.ParameterException; import com.sk89q.worldedit.world.World; +import com.sk89q.worldedit.world.biome.BaseBiome; +import com.sk89q.worldedit.world.biome.Biomes; +import com.sk89q.worldedit.world.registry.BiomeRegistry; import java.util.Arrays; +import java.util.List; /** * Binds standard WorldEdit classes such as {@link Player} and {@link LocalSession}. @@ -288,25 +291,40 @@ public class WorldEditBinding extends BindingHelper { } /** - * Gets an {@link BiomeType} from a {@link ArgumentStack}. + * Gets an {@link BaseBiome} from a {@link ArgumentStack}. * * @param context the context * @return a pattern * @throws ParameterException on error * @throws WorldEditException on error */ - @BindingMatch(type = BiomeType.class, + @BindingMatch(type = BaseBiome.class, behavior = BindingBehavior.CONSUMES, consumedCount = 1) - public BiomeType getBiomeType(ArgumentStack context) throws ParameterException, WorldEditException { + public BaseBiome getBiomeType(ArgumentStack context) throws ParameterException, WorldEditException { String input = context.next(); if (input != null) { - BiomeType type = worldEdit.getServer().getBiomes().get(input); - if (type != null) { - return type; + Actor actor = context.getContext().getLocals().get(Actor.class); + World world; + if (actor instanceof Entity) { + Extent extent = ((Entity) actor).getExtent(); + if (extent instanceof World) { + world = (World) extent; + } else { + throw new ParameterException("A world is required."); + } + } else { + throw new ParameterException("An entity is required."); + } + + BiomeRegistry biomeRegistry = world.getWorldData().getBiomeRegistry(); + List knownBiomes = biomeRegistry.getBiomes(); + BaseBiome biome = Biomes.findBiomeByName(knownBiomes, input, biomeRegistry); + if (biome != null) { + return biome; } else { throw new ParameterException( - String.format("Can't recognize biome type '%s' -- use //biomelist to list available types", input)); + String.format("Can't recognize biome type '%s' -- use /biomelist to list available types", input)); } } else { throw new ParameterException( diff --git a/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryBiomeShape.java b/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryBiomeShape.java index 2da795df9..bb8edb3b9 100644 --- a/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryBiomeShape.java +++ b/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryBiomeShape.java @@ -19,12 +19,12 @@ package com.sk89q.worldedit.regions.shape; -import com.sk89q.worldedit.BiomeType; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.FlatRegion; import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.world.biome.BaseBiome; /** * Generates solid and hollow shapes according to materials returned by the @@ -58,7 +58,7 @@ public abstract class ArbitraryBiomeShape { cacheSizeX = (int) (max.getX() - cacheOffsetX + 2); cacheSizeZ = (int) (max.getZ() - cacheOffsetZ + 2); - cache = new BiomeType[cacheSizeX * cacheSizeZ]; + cache = new BaseBiome[cacheSizeX * cacheSizeZ]; } protected Iterable getExtent() { @@ -72,24 +72,24 @@ public abstract class ArbitraryBiomeShape { * OUTSIDE = outside * else = inside */ - private final BiomeType[] cache; + private final BaseBiome[] cache; /** * Override this function to specify the shape to generate. * * @param x X coordinate to be queried * @param z Z coordinate to be queried - * @param defaultBiomeType The default biome for the current column. + * @param defaultBaseBiome The default biome for the current column. * @return material to place or null to not place anything. */ - protected abstract BiomeType getBiome(int x, int z, BiomeType defaultBiomeType); + protected abstract BaseBiome getBiome(int x, int z, BaseBiome defaultBaseBiome); - private BiomeType getBiomeCached(int x, int z, BiomeType biomeType) { + private BaseBiome getBiomeCached(int x, int z, BaseBiome BaseBiome) { final int index = (z - cacheOffsetZ) + (x - cacheOffsetX) * cacheSizeZ; - final BiomeType cacheEntry = cache[index]; + final BaseBiome cacheEntry = cache[index]; if (cacheEntry == null) {// unknown, fetch material - final BiomeType material = getBiome(x, z, biomeType); + final BaseBiome material = getBiome(x, z, BaseBiome); if (material == null) { // outside cache[index] = OUTSIDE; @@ -108,13 +108,13 @@ public abstract class ArbitraryBiomeShape { return cacheEntry; } - private boolean isInsideCached(int x, int z, BiomeType biomeType) { + private boolean isInsideCached(int x, int z, BaseBiome BaseBiome) { final int index = (z - cacheOffsetZ) + (x - cacheOffsetX) * cacheSizeZ; - final BiomeType cacheEntry = cache[index]; + final BaseBiome cacheEntry = cache[index]; if (cacheEntry == null) { // unknown block, meaning they must be outside the extent at this stage, but might still be inside the shape - return getBiomeCached(x, z, biomeType) != null; + return getBiomeCached(x, z, BaseBiome) != null; } return cacheEntry != OUTSIDE; @@ -124,11 +124,11 @@ public abstract class ArbitraryBiomeShape { * Generates the shape. * * @param editSession The EditSession to use. - * @param biomeType The default biome type. + * @param BaseBiome The default biome type. * @param hollow Specifies whether to generate a hollow shape. * @return number of affected blocks. */ - public int generate(EditSession editSession, BiomeType biomeType, boolean hollow) { + public int generate(EditSession editSession, BaseBiome BaseBiome, boolean hollow) { int affected = 0; for (Vector2D position : getExtent()) { @@ -136,7 +136,7 @@ public abstract class ArbitraryBiomeShape { int z = position.getBlockZ(); if (!hollow) { - final BiomeType material = getBiome(x, z, biomeType); + final BaseBiome material = getBiome(x, z, BaseBiome); if (material != OUTSIDE) { editSession.getWorld().setBiome(position, material); ++affected; @@ -145,26 +145,26 @@ public abstract class ArbitraryBiomeShape { continue; } - final BiomeType material = getBiomeCached(x, z, biomeType); + final BaseBiome material = getBiomeCached(x, z, BaseBiome); if (material == null) { continue; } boolean draw = false; do { - if (!isInsideCached(x + 1, z, biomeType)) { + if (!isInsideCached(x + 1, z, BaseBiome)) { draw = true; break; } - if (!isInsideCached(x - 1, z, biomeType)) { + if (!isInsideCached(x - 1, z, BaseBiome)) { draw = true; break; } - if (!isInsideCached(x, z + 1, biomeType)) { + if (!isInsideCached(x, z + 1, BaseBiome)) { draw = true; break; } - if (!isInsideCached(x, z - 1, biomeType)) { + if (!isInsideCached(x, z - 1, BaseBiome)) { draw = true; break; } @@ -181,9 +181,15 @@ public abstract class ArbitraryBiomeShape { return affected; } - private static final BiomeType OUTSIDE = new BiomeType() { - public String getName() { - throw new UnsupportedOperationException(); + private static final BaseBiome OUTSIDE = new BaseBiome(0) { + @Override + public int hashCode() { + return 0; + } + + @Override + public boolean equals(Object o) { + return this == o; } }; } diff --git a/src/main/java/com/sk89q/worldedit/util/WeightedChoice.java b/src/main/java/com/sk89q/worldedit/util/WeightedChoice.java new file mode 100644 index 000000000..3e5d5d440 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/util/WeightedChoice.java @@ -0,0 +1,118 @@ +/* + * 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 Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.util; + +import com.google.common.base.Function; +import com.google.common.base.Optional; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Returns the best choice given a weighting function and a target weight. + * + *

A function must be supplied that returns a numeric score for each + * choice. The function can return null to mean that the choice should + * not be considered.

+ * + * @param the type of choice + */ +public class WeightedChoice { + + private final Function function; + private double target; + private double best; + private T current; + + /** + * Create a new instance. + * + * @param function a function that assigns a score for each choice + * @param target the target score that the best choice should be closest to + */ + public WeightedChoice(Function function, double target) { + checkNotNull(function); + this.function = function; + this.target = target; + } + + /** + * Consider the given object. + * + * @param object the choice + */ + public void consider(T object) { + checkNotNull(object); + Number value = checkNotNull(function.apply(object)); + if (value != null) { + double distance = Math.abs(target - value.doubleValue()); + if (current == null || distance <= best) { + best = distance; + current = object; + } + } + } + + /** + * Get the best choice. + * + * @return the best choice + */ + public Optional> getChoice() { + if (current != null) { + return Optional.of(new Choice(current, best)); + } else { + return Optional.absent(); + } + } + + /** + * A tuple of choice and score. + * + * @param the choice type + */ + public static class Choice { + private final T object; + private final double value; + + private Choice(T object, double value) { + this.object = object; + this.value = value; + } + + /** + * Get the chosen value. + * + * @return the value + */ + public T getValue() { + return object; + } + + /** + * Get the score. + * + * @return the score + */ + public double getScore() { + return value; + } + } + +} diff --git a/src/main/java/com/sk89q/worldedit/util/function/LevenshteinDistance.java b/src/main/java/com/sk89q/worldedit/util/function/LevenshteinDistance.java new file mode 100644 index 000000000..8767f3a2f --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/util/function/LevenshteinDistance.java @@ -0,0 +1,192 @@ +/* + * 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 Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.util.function; + +import com.google.common.base.Function; + +import javax.annotation.Nullable; +import java.util.regex.Pattern; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Provides a Levenshtein distance between a given string and each string + * that this function is applied to. + */ +public class LevenshteinDistance implements Function { + + public final static Pattern STANDARD_CHARS = Pattern.compile("[ _\\-]"); + + private final String baseString; + private final boolean caseSensitive; + private final Pattern replacePattern; + + /** + * Create a new instance. + * + * @param baseString the string to compare to + * @param caseSensitive true to make case sensitive comparisons + */ + public LevenshteinDistance(String baseString, boolean caseSensitive) { + this(baseString, caseSensitive, null); + } + + /** + * Create a new instance. + * + * @param baseString the string to compare to + * @param caseSensitive true to make case sensitive comparisons + * @param replacePattern pattern to match characters to be removed in both the input and test strings (may be null) + */ + public LevenshteinDistance(String baseString, boolean caseSensitive, @Nullable Pattern replacePattern) { + checkNotNull(baseString); + this.caseSensitive = caseSensitive; + this.replacePattern = replacePattern; + baseString = caseSensitive ? baseString : baseString.toLowerCase(); + baseString = replacePattern != null ? replacePattern.matcher(baseString).replaceAll("") : baseString; + this.baseString = baseString; + } + + @Nullable + @Override + public Integer apply(String input) { + if (input == null) { + return null; + } + + if (replacePattern != null) { + input = replacePattern.matcher(input).replaceAll(""); + } + + if (caseSensitive) { + return distance(baseString, input); + } else { + return distance(baseString, input.toLowerCase()); + } + } + + /** + *

Find the Levenshtein distance between two Strings.

+ * + *

This is the number of changes needed to change one String into + * another, where each change is a single character modification (deletion, + * insertion or substitution).

+ * + *

The previous implementation of the Levenshtein distance algorithm + * was from http://www.merriampark.com/ld.htm

+ * + *

Chas Emerick has written an implementation in Java, which avoids an OutOfMemoryError + * which can occur when my Java implementation is used with very large strings.
+ * This implementation of the Levenshtein distance algorithm + * is from http://www.merriampark.com/ldjava.htm

+ * + *
+     * distance(null, *)             = IllegalArgumentException
+     * distance(*, null)             = IllegalArgumentException
+     * distance("","")               = 0
+     * distance("","a")              = 1
+     * distance("aaapppp", "")       = 7
+     * distance("frog", "fog")       = 1
+     * distance("fly", "ant")        = 3
+     * distance("elephant", "hippo") = 7
+     * distance("hippo", "elephant") = 7
+     * distance("hippo", "zzzzzzzz") = 8
+     * distance("hello", "hallo")    = 1
+     * 
+ * + * @param s the first String, must not be null + * @param t the second String, must not be null + * @return result distance + * @throws IllegalArgumentException if either String input null + */ + public static int distance(String s, String t) { + if (s == null || t == null) { + throw new IllegalArgumentException("Strings must not be null"); + } + + /* + * The difference between this impl. and the previous is that, rather + * than creating and retaining a matrix of size s.length()+1 by + * t.length()+1, we maintain two single-dimensional arrays of length + * s.length()+1. The first, d, is the 'current working' distance array + * that maintains the newest distance cost counts as we iterate through + * the characters of String s. Each time we increment the index of + * String t we are comparing, d is copied to p, the second int[]. Doing + * so allows us to retain the previous cost counts as required by the + * algorithm (taking the minimum of the cost count to the left, up one, + * and diagonally up and to the left of the current cost count being + * calculated). (Note that the arrays aren't really copied anymore, just + * switched...this is clearly much better than cloning an array or doing + * a System.arraycopy() each time through the outer loop.) + * + * Effectively, the difference between the two implementations is this + * one does not cause an out of memory condition when calculating the LD + * over two very large strings. + */ + + int n = s.length(); // length of s + int m = t.length(); // length of t + + if (n == 0) { + return m; + } else if (m == 0) { + return n; + } + + int p[] = new int[n + 1]; // 'previous' cost array, horizontally + int d[] = new int[n + 1]; // cost array, horizontally + int _d[]; // placeholder to assist in swapping p and d + + // indexes into strings s and t + int i; // iterates through s + int j; // iterates through t + + char tj; // jth character of t + + int cost; // cost + + for (i = 0; i <= n; ++i) { + p[i] = i; + } + + for (j = 1; j <= m; ++j) { + tj = t.charAt(j - 1); + d[0] = j; + + for (i = 1; i <= n; ++i) { + cost = s.charAt(i - 1) == tj ? 0 : 1; + // minimum of cell to the left+1, to the top+1, diagonally left + // and up +cost + d[i] = Math.min(Math.min(d[i - 1] + 1, p[i] + 1), p[i - 1] + + cost); + } + + // copy current distance counts to 'previous row' distance counts + _d = p; + p = d; + d = _d; + } + + // our last action in the above loop was to switch d and p, so p now + // actually has the most recent cost counts + return p[n]; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/world/NullWorld.java b/src/main/java/com/sk89q/worldedit/world/NullWorld.java index 3b0854dc6..cfb141a42 100644 --- a/src/main/java/com/sk89q/worldedit/world/NullWorld.java +++ b/src/main/java/com/sk89q/worldedit/world/NullWorld.java @@ -19,7 +19,11 @@ package com.sk89q.worldedit.world; -import com.sk89q.worldedit.*; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.Vector2D; +import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.BlockID; @@ -28,6 +32,7 @@ import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.TreeGenerator.TreeType; +import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.registry.LegacyWorldData; import com.sk89q.worldedit.world.registry.WorldData; @@ -62,12 +67,13 @@ public class NullWorld extends AbstractWorld { } @Override - public BiomeType getBiome(Vector2D position) { + public BaseBiome getBiome(Vector2D position) { return null; } @Override - public void setBiome(Vector2D position, BiomeType biome) { + public boolean setBiome(Vector2D position, BaseBiome biome) { + return false; } @Override diff --git a/src/main/java/com/sk89q/worldedit/world/World.java b/src/main/java/com/sk89q/worldedit/world/World.java index bd2d13d1c..657f510e3 100644 --- a/src/main/java/com/sk89q/worldedit/world/World.java +++ b/src/main/java/com/sk89q/worldedit/world/World.java @@ -19,12 +19,10 @@ package com.sk89q.worldedit.world; -import com.sk89q.worldedit.BiomeType; import com.sk89q.worldedit.BlockVector2D; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseItemStack; @@ -147,22 +145,6 @@ public interface World extends Extent { */ boolean clearContainerBlockContents(Vector position); - /** - * Get the biome type. - * - * @param position the (x, z) location to check the biome at - * @return the biome type at the location - */ - BiomeType getBiome(Vector2D position); - - /** - * Set the biome type. - * - * @param position the (x, z) location to set the biome at - * @param biome the biome type to set to - */ - void setBiome(Vector2D position, BiomeType biome); - /** * Drop an item at the given position. * diff --git a/src/main/java/com/sk89q/worldedit/world/biome/BaseBiome.java b/src/main/java/com/sk89q/worldedit/world/biome/BaseBiome.java new file mode 100644 index 000000000..f60299f66 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/world/biome/BaseBiome.java @@ -0,0 +1,82 @@ +/* + * 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 Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.world.biome; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Basic storage object to represent a given biome. + */ +public class BaseBiome { + + private int id; + + /** + * Create a new biome with the given biome ID. + * + * @param id the biome ID + */ + public BaseBiome(int id) { + this.id = id; + } + + /** + * Create a clone of the given biome. + * + * @param biome the biome to clone + */ + public BaseBiome(BaseBiome biome) { + checkNotNull(biome); + this.id = biome.getId(); + } + + /** + * Get the biome ID. + * + * @return the biome ID + */ + public int getId() { + return id; + } + + /** + * Set the biome id. + * + * @param id the biome ID + */ + public void setId(int id) { + this.id = id; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + BaseBiome baseBiome = (BaseBiome) o; + + return id == baseBiome.id; + } + + @Override + public int hashCode() { + return id; + } +} diff --git a/src/main/java/com/sk89q/worldedit/BiomeType.java b/src/main/java/com/sk89q/worldedit/world/biome/BiomeData.java similarity index 74% rename from src/main/java/com/sk89q/worldedit/BiomeType.java rename to src/main/java/com/sk89q/worldedit/world/biome/BiomeData.java index 93d9efe4a..5f21dd978 100644 --- a/src/main/java/com/sk89q/worldedit/BiomeType.java +++ b/src/main/java/com/sk89q/worldedit/world/biome/BiomeData.java @@ -17,20 +17,19 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit; +package com.sk89q.worldedit.world.biome; -public interface BiomeType { - - public static final BiomeType UNKNOWN = new BiomeType() { - public String getName() { - return "Unknown"; - } - }; +/** + * Provides information about a biome. + */ +public interface BiomeData { /** - * Get the name of this biome type. + * Get the name of the biome, which does not have to follow any + * particular convention. * - * @return String + * @return the biome's name */ - public String getName(); + String getName(); + } diff --git a/src/main/java/com/sk89q/worldedit/world/biome/BiomeName.java b/src/main/java/com/sk89q/worldedit/world/biome/BiomeName.java new file mode 100644 index 000000000..145d891cb --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/world/biome/BiomeName.java @@ -0,0 +1,57 @@ +/* + * 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 Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.world.biome; + +import com.google.common.base.Function; +import com.sk89q.worldedit.world.registry.BiomeRegistry; + +import javax.annotation.Nullable; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Returns the name of a biome using a given {@code BiomeRegistry}. + */ +class BiomeName implements Function { + + private final BiomeRegistry registry; + + /** + * Create a new instance. + * + * @param registry the biome registry + */ + BiomeName(BiomeRegistry registry) { + checkNotNull(registry); + this.registry = registry; + } + + @Nullable + @Override + public String apply(BaseBiome input) { + BiomeData data = registry.getData(input); + if (data != null) { + return data.getName(); + } else { + return null; + } + } + +} diff --git a/src/main/java/com/sk89q/worldedit/world/biome/Biomes.java b/src/main/java/com/sk89q/worldedit/world/biome/Biomes.java new file mode 100644 index 000000000..c19c2ac93 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/world/biome/Biomes.java @@ -0,0 +1,70 @@ +/* + * 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 Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.world.biome; + +import com.google.common.base.Function; +import com.google.common.base.Functions; +import com.google.common.base.Optional; +import com.sk89q.worldedit.util.WeightedChoice; +import com.sk89q.worldedit.util.WeightedChoice.Choice; +import com.sk89q.worldedit.util.function.LevenshteinDistance; +import com.sk89q.worldedit.world.registry.BiomeRegistry; + +import javax.annotation.Nullable; +import java.util.Collection; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Utility methods related to biomes. + */ +public final class Biomes { + + private Biomes() { + } + + /** + * Find a biome that matches the given input name. + * + * @param biomes a list of biomes + * @param name the name to test + * @param registry a biome registry + * @return a biome or null + */ + @Nullable + public static BaseBiome findBiomeByName(Collection biomes, String name, BiomeRegistry registry) { + checkNotNull(biomes); + checkNotNull(name); + checkNotNull(registry); + + Function compare = new LevenshteinDistance(name, false, LevenshteinDistance.STANDARD_CHARS); + WeightedChoice chooser = new WeightedChoice(Functions.compose(compare, new BiomeName(registry)), 0); + for (BaseBiome biome : biomes) { + chooser.consider(biome); + } + Optional> choice = chooser.getChoice(); + if (choice.isPresent() && choice.get().getScore() <= 1) { + return choice.get().getValue(); + } else { + return null; + } + } + +} diff --git a/src/main/java/com/sk89q/worldedit/BiomeTypes.java b/src/main/java/com/sk89q/worldedit/world/registry/BiomeRegistry.java similarity index 56% rename from src/main/java/com/sk89q/worldedit/BiomeTypes.java rename to src/main/java/com/sk89q/worldedit/world/registry/BiomeRegistry.java index 0d61b4c80..ab3942463 100644 --- a/src/main/java/com/sk89q/worldedit/BiomeTypes.java +++ b/src/main/java/com/sk89q/worldedit/world/registry/BiomeRegistry.java @@ -17,31 +17,42 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit; +package com.sk89q.worldedit.world.registry; +import com.sk89q.worldedit.world.biome.BaseBiome; +import com.sk89q.worldedit.world.biome.BiomeData; + +import javax.annotation.Nullable; import java.util.List; -public interface BiomeTypes { +/** + * Provides information on biomes. + */ +public interface BiomeRegistry { /** - * Returns if a biome with the given name is available. + * Create a new biome given its biome ID. * - * @param name - * @return + * @param id its biome ID + * @return a new biome or null if it can't be created */ - boolean has(String name); + @Nullable + BaseBiome createFromId(int id); /** - * Returns the biome type for the given name + * Get a list of available biomes. * - * @return + * @return a list of biomes */ - BiomeType get(String name) throws UnknownBiomeTypeException; + List getBiomes(); /** - * Returns a list of all available biome types. + * Get data about a biome. * - * @return + * @param biome the biome + * @return a data object or null if information is not known */ - List all(); + @Nullable + BiomeData getData(BaseBiome biome); + } diff --git a/src/main/java/com/sk89q/worldedit/world/registry/LegacyWorldData.java b/src/main/java/com/sk89q/worldedit/world/registry/LegacyWorldData.java index bed5b401f..2fabd886d 100644 --- a/src/main/java/com/sk89q/worldedit/world/registry/LegacyWorldData.java +++ b/src/main/java/com/sk89q/worldedit/world/registry/LegacyWorldData.java @@ -23,16 +23,17 @@ package com.sk89q.worldedit.world.registry; * An implementation of {@link WorldData} that uses legacy numeric IDs and * a built-in block database. */ -public final class LegacyWorldData implements WorldData { +public class LegacyWorldData implements WorldData { private static final LegacyWorldData INSTANCE = new LegacyWorldData(); private final LegacyBlockRegistry blockRegistry = new LegacyBlockRegistry(); private final NullEntityRegistry entityRegistry = new NullEntityRegistry(); + private final NullBiomeRegistry biomeRegistry = new NullBiomeRegistry(); /** * Create a new instance. */ - private LegacyWorldData() { + protected LegacyWorldData() { } @Override @@ -45,6 +46,11 @@ public final class LegacyWorldData implements WorldData { return entityRegistry; } + @Override + public BiomeRegistry getBiomeRegistry() { + return biomeRegistry; + } + /** * Get a singleton instance. * diff --git a/src/main/java/com/sk89q/worldedit/world/registry/NullBiomeRegistry.java b/src/main/java/com/sk89q/worldedit/world/registry/NullBiomeRegistry.java new file mode 100644 index 000000000..8bbf7c1ff --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/world/registry/NullBiomeRegistry.java @@ -0,0 +1,57 @@ +/* + * 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 Lesser 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.world.registry; + +import com.sk89q.worldedit.world.biome.BaseBiome; +import com.sk89q.worldedit.world.biome.BiomeData; + +import javax.annotation.Nullable; +import java.util.Collections; +import java.util.List; + +/** + * A biome registry that knows nothing. + */ +public class NullBiomeRegistry implements BiomeRegistry { + + /** + * Create a new instance. + */ + public NullBiomeRegistry() { + } + + @Nullable + @Override + public BaseBiome createFromId(int id) { + return null; + } + + @Override + public List getBiomes() { + return Collections.emptyList(); + } + + @Nullable + @Override + public BiomeData getData(BaseBiome biome) { + return null; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/world/registry/WorldData.java b/src/main/java/com/sk89q/worldedit/world/registry/WorldData.java index d8bf886e6..d6a4b21f8 100644 --- a/src/main/java/com/sk89q/worldedit/world/registry/WorldData.java +++ b/src/main/java/com/sk89q/worldedit/world/registry/WorldData.java @@ -39,4 +39,11 @@ public interface WorldData { */ EntityRegistry getEntityRegistry(); + /** + * Get the biome registry. + * + * @return the biome registry + */ + BiomeRegistry getBiomeRegistry(); + }