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 bc0031773..20b3c1930 100644
Binary files a/src/bukkit/resources/com/sk89q/worldedit/bukkit/adapter/impl/CraftBukkit_v1_7_R2.class and b/src/bukkit/resources/com/sk89q/worldedit/bukkit/adapter/impl/CraftBukkit_v1_7_R2.class differ
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 188b0becc..1f8cc436f 100644
Binary files a/src/bukkit/resources/com/sk89q/worldedit/bukkit/adapter/impl/CraftBukkit_v1_7_R3.class and b/src/bukkit/resources/com/sk89q/worldedit/bukkit/adapter/impl/CraftBukkit_v1_7_R3.class differ
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 b60c4898d..f9eb46a5d 100644
Binary files a/src/bukkit/resources/com/sk89q/worldedit/bukkit/adapter/impl/CraftBukkit_v1_7_R4.class and b/src/bukkit/resources/com/sk89q/worldedit/bukkit/adapter/impl/CraftBukkit_v1_7_R4.class differ
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();
+
}