├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── IslandCraft-Common └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ ├── util │ ├── Cache.java │ ├── CacheLoader.java │ ├── StringUtils.java │ ├── EternalLoadingCache.java │ └── ExpiringLoadingCache.java │ └── core │ ├── noise │ ├── Noise.java │ └── OctaveNoise.java │ ├── ICWorldConfig.java │ ├── mosaic │ ├── RangeEntry.java │ ├── Site.java │ ├── Grid.java │ ├── AngleComparator.java │ ├── RangeList.java │ └── Poisson.java │ ├── ICLogger.java │ ├── IslandDatabase.java │ ├── DefaultIslandCraft.java │ ├── ConstantBiomeDistribution.java │ ├── EmptyIslandGenerator.java │ ├── ConstantIslandGenerator.java │ ├── EmptyIslandDistribution.java │ ├── IslandCache.java │ ├── ICClassLoader.java │ ├── DefaultIsland.java │ ├── IslandGeneratorAlpha.java │ ├── SquareIslandDistribution.java │ ├── DefaultWorld.java │ └── HexagonalIslandDistribution.java ├── IslandCraft-Bukkit └── src │ └── main │ ├── resources │ ├── plugin.yml │ └── config.yml │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── bukkit │ ├── JavaUtilLogger.java │ ├── IslandCraftBiomeGenerator.java │ ├── BukkitWorldConfig.java │ ├── BiomeGeneratorListener.java │ ├── EbeanServerUtil.java │ ├── EbeanServerIslandDatabase.java │ └── IslandCraftPlugin.java ├── IslandCraft-Sponge └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ ├── Slf4jLogger.java │ ├── IslandCraftGeneratorModifier.java │ ├── IslandCraftPlugin.java │ ├── SpongeWorldConfig.java │ ├── JdbcIslandDatabase.java │ └── IslandCraftBiomeGenerator.java ├── IslandCraft-API └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── api │ ├── IslandCraft.java │ ├── BiomeDistribution.java │ ├── IslandGenerator.java │ ├── ICLocation.java │ ├── ICBiome.java │ ├── ICRegion.java │ ├── IslandDistribution.java │ ├── ICIsland.java │ └── ICWorld.java ├── settings.gradle ├── README.md ├── IslandCraft-NMS └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── nms │ ├── NmsWrapper.java │ └── BiomeGenerator.java ├── IslandCraft-NMS-v1_4_R1 └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── nms │ └── v1_4_R1 │ └── NmsHandler.java ├── IslandCraft-NMS-v1_5_R1 └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── nms │ └── v1_5_R1 │ └── NmsHandler.java ├── IslandCraft-NMS-v1_5_R2 └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── nms │ └── v1_5_R2 │ └── NmsHandler.java ├── IslandCraft-NMS-v1_5_R3 └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── nms │ └── v1_5_R3 │ └── NmsHandler.java ├── IslandCraft-NMS-v1_6_R1 └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── nms │ └── v1_6_R1 │ └── NmsHandler.java ├── IslandCraft-NMS-v1_6_R2 └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── nms │ └── v1_6_R2 │ └── NmsHandler.java ├── IslandCraft-NMS-v1_6_R3 └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── nms │ └── v1_6_R3 │ └── NmsHandler.java ├── IslandCraft-NMS-v1_7_R1 └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── nms │ └── v1_7_R1 │ ├── NmsHandler.java │ └── CustomWorldChunkManager.java ├── IslandCraft-NMS-v1_7_R2 └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── nms │ └── v1_7_R2 │ ├── NmsHandler.java │ └── CustomWorldChunkManager.java ├── IslandCraft-NMS-v1_7_R3 └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── nms │ └── v1_7_R3 │ └── NmsHandler.java ├── IslandCraft-NMS-v1_7_R4 └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── nms │ └── v1_7_R4 │ └── NmsHandler.java ├── LICENSE ├── IslandCraft-NMS-v1_8_R1 └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── nms │ └── v1_8_R1 │ └── NmsHandler.java ├── IslandCraft-NMS-v1_8_R2 └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── nms │ └── v1_8_R2 │ └── NmsHandler.java ├── IslandCraft-NMS-v1_8_R3 └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── nms │ └── v1_8_R3 │ └── NmsHandler.java ├── IslandCraft-NMS-v1_9_R1 └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── nms │ └── v1_9_R1 │ └── NmsHandler.java ├── IslandCraft-NMS-v1_9_R2 └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── nms │ └── v1_9_R2 │ └── NmsHandler.java ├── IslandCraft-NMS-v1_10_R1 └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── nms │ └── v1_10_R1 │ └── NmsHandler.java ├── IslandCraft-NMS-v1_11_R1 └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── nms │ └── v1_11_R1 │ └── NmsHandler.java ├── IslandCraft-NMS-v1_12_R1 └── src │ └── main │ └── java │ └── com │ └── github │ └── hoqhuuep │ └── islandcraft │ └── nms │ └── v1_12_R1 │ └── NmsHandler.java ├── gradlew.bat └── gradlew /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoqhuuep/IslandCraft/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/bin/ 2 | **/build/ 3 | **/.settings/ 4 | /.checkstyle/ 5 | /.gradle/ 6 | *.class 7 | *.classpath 8 | *.jar 9 | !/gradle/wrapper/gradle-wrapper.jar 10 | *.project 11 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/util/Cache.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.util; 2 | 3 | public interface Cache { 4 | V get(K key); 5 | } 6 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/util/CacheLoader.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.util; 2 | 3 | public interface CacheLoader { 4 | V load(K key); 5 | } 6 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/noise/Noise.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core.noise; 2 | 3 | public interface Noise { 4 | /** Returns noise value in range [0, 1] **/ 5 | double noise(double x, double z); 6 | } 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Feb 10 20:39:05 AEDT 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.11-bin.zip 7 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/ICWorldConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core; 2 | 3 | public interface ICWorldConfig { 4 | String getOcean(); 5 | 6 | String getIslandDistribution(); 7 | 8 | String[] getIslandGenerstors(); 9 | } 10 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/mosaic/RangeEntry.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core.mosaic; 2 | 3 | public final class RangeEntry { 4 | public double min; 5 | public double max; 6 | 7 | public RangeEntry(final double min, final double max) { 8 | this.min = min; 9 | this.max = max; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/ICLogger.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core; 2 | 3 | public abstract class ICLogger { 4 | public static ICLogger logger = null; 5 | 6 | public abstract void info(String message); 7 | public abstract void warning(String message); 8 | public abstract void error(String message); 9 | } 10 | -------------------------------------------------------------------------------- /IslandCraft-Bukkit/src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: IslandCraft 2 | version: 1.0.8 3 | description: Changes the biome distribution of the world to create an ocean with islands 4 | author: hoqhuuep 5 | website: http://dev.bukkit.org/bukkit-plugins/islandcraft/ 6 | main: com.github.hoqhuuep.islandcraft.bukkit.IslandCraftPlugin 7 | load: STARTUP 8 | commands: 9 | ic: 10 | description: IslandCraft commands 11 | aliases: [island,islandcraft] -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/util/StringUtils.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.util; 2 | 3 | public class StringUtils { 4 | public static String join(String[] array, String sepeator) { 5 | if (array.length == 0) { 6 | return ""; 7 | } 8 | StringBuilder result = new StringBuilder(); 9 | result.append(array[0]); 10 | for (int i = 1; i < array.length; ++i) { 11 | result.append(sepeator); 12 | result.append(array[i]); 13 | } 14 | return result.toString(); 15 | } 16 | 17 | public static boolean equals(String a, String b) { 18 | return (a == null && b == null) || (a != null && a.equals(b)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /IslandCraft-Sponge/src/main/java/com/github/hoqhuuep/islandcraft/Slf4jLogger.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft; 2 | 3 | import org.slf4j.Logger; 4 | 5 | import com.github.hoqhuuep.islandcraft.core.ICLogger; 6 | 7 | public class Slf4jLogger extends ICLogger { 8 | private final Logger logger; 9 | 10 | public Slf4jLogger(Logger logger) { 11 | this.logger = logger; 12 | } 13 | 14 | @Override 15 | public void info(String message) { 16 | logger.info(message); 17 | } 18 | 19 | @Override 20 | public void warning(String message) { 21 | logger.warn(message); 22 | } 23 | 24 | @Override 25 | public void error(String message) { 26 | logger.error(message); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/noise/OctaveNoise.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core.noise; 2 | 3 | import java.util.Random; 4 | 5 | public class OctaveNoise implements Noise { 6 | private SimplexNoise octave1; 7 | private SimplexNoise octave2; 8 | 9 | public OctaveNoise(long seed) { 10 | Random random = new Random(seed); 11 | octave1 = new SimplexNoise(random); 12 | octave2 = new SimplexNoise(random); 13 | } 14 | 15 | @Override 16 | public double noise(double x, double y) { 17 | double noise1 = octave1.noise(x, y, 0.0); 18 | double noise2 = octave2.noise(x * 2.0, y * 2.0, 0.0) * 0.5; 19 | return (noise1 + noise2) / 3.0 + 0.5; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /IslandCraft-Bukkit/src/main/java/com/github/hoqhuuep/islandcraft/bukkit/JavaUtilLogger.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.bukkit; 2 | 3 | import java.util.logging.Logger; 4 | 5 | import com.github.hoqhuuep.islandcraft.core.ICLogger; 6 | 7 | public class JavaUtilLogger extends ICLogger { 8 | private final Logger logger; 9 | 10 | public JavaUtilLogger(Logger logger) { 11 | this.logger = logger; 12 | } 13 | 14 | @Override 15 | public void info(String message) { 16 | logger.info(message); 17 | } 18 | 19 | @Override 20 | public void warning(String message) { 21 | logger.warning(message); 22 | } 23 | 24 | @Override 25 | public void error(String message) { 26 | logger.severe(message); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /IslandCraft-API/src/main/java/com/github/hoqhuuep/islandcraft/api/IslandCraft.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.api; 2 | 3 | import java.util.Set; 4 | 5 | public interface IslandCraft { 6 | /** 7 | * Returns the ICWorld for the world with the given name. 8 | * 9 | * @param worldName 10 | * the name of the world 11 | * @return the ICWorld or null if the world does not exist or IslandCraft is 12 | * not enabled for the world in config.yml 13 | */ 14 | ICWorld getWorld(String worldName); 15 | 16 | /** 17 | * Add an ICWorld 18 | * @param world 19 | */ 20 | void addWorld(ICWorld world); 21 | 22 | /** 23 | * Returns all the worlds for which IslandCraft has been enabled. 24 | */ 25 | Set getWorlds(); 26 | } 27 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/util/EternalLoadingCache.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.util; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class EternalLoadingCache implements Cache { 7 | private final CacheLoader loader; 8 | private final Map cache = new HashMap(); 9 | 10 | public EternalLoadingCache(CacheLoader loader) { 11 | this.loader = loader; 12 | } 13 | 14 | @Override 15 | public V get(K key) { 16 | // Try to get value from cache 17 | V value = cache.get(key); 18 | if (value != null) { 19 | return value; 20 | } 21 | // Otherwise generate new value using loader 22 | value = loader.load(key); 23 | if (value != null) { 24 | cache.put(key, value); 25 | } 26 | return value; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/mosaic/Site.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core.mosaic; 2 | 3 | import java.awt.Polygon; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public final class Site { 8 | public final double x; 9 | public final double z; 10 | public final List suspectNeighbors; 11 | public final List neighbors; 12 | public Site parent; 13 | public Polygon polygon; 14 | public boolean isOcean; 15 | public boolean isOuterCoast; 16 | public boolean isInnerCoast; 17 | 18 | public Site(final double x, final double z) { 19 | this.x = x; 20 | this.z = z; 21 | suspectNeighbors = new ArrayList(); 22 | neighbors = new ArrayList(); 23 | polygon = new Polygon(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /IslandCraft-API/src/main/java/com/github/hoqhuuep/islandcraft/api/BiomeDistribution.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.api; 2 | 3 | /** 4 | * Controls the distribution of biomes in a Minecraft world. 5 | */ 6 | public interface BiomeDistribution { 7 | /** 8 | * Returns the biome to be generated at the given location in a world with 9 | * the given random seed. 10 | * 11 | * @param x 12 | * the x-coordinate of the location to get the biome at (measured 13 | * in blocks) 14 | * @param z 15 | * the z-coordinate of the location to get the biome at (measured 16 | * in blocks) 17 | * @param worldSeed 18 | * the random seed of the world to get the biome from 19 | * @return the biome to generate 20 | */ 21 | ICBiome biomeAt(int x, int z, long worldSeed); 22 | } 23 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include 'IslandCraft-API' 2 | include 'IslandCraft-Common' 3 | include 'IslandCraft-Bukkit' 4 | include 'IslandCraft-Sponge' 5 | include 'IslandCraft-NMS' 6 | include 'IslandCraft-NMS-v1_4_R1' 7 | include 'IslandCraft-NMS-v1_5_R1' 8 | include 'IslandCraft-NMS-v1_5_R2' 9 | include 'IslandCraft-NMS-v1_5_R3' 10 | include 'IslandCraft-NMS-v1_6_R1' 11 | include 'IslandCraft-NMS-v1_6_R2' 12 | include 'IslandCraft-NMS-v1_6_R3' 13 | include 'IslandCraft-NMS-v1_7_R1' 14 | include 'IslandCraft-NMS-v1_7_R2' 15 | include 'IslandCraft-NMS-v1_7_R3' 16 | include 'IslandCraft-NMS-v1_7_R4' 17 | include 'IslandCraft-NMS-v1_8_R1' 18 | include 'IslandCraft-NMS-v1_8_R2' 19 | include 'IslandCraft-NMS-v1_8_R3' 20 | include 'IslandCraft-NMS-v1_9_R1' 21 | include 'IslandCraft-NMS-v1_9_R2' 22 | include 'IslandCraft-NMS-v1_10_R1' 23 | include 'IslandCraft-NMS-v1_11_R1' 24 | include 'IslandCraft-NMS-v1_12_R1' 25 | -------------------------------------------------------------------------------- /IslandCraft-API/src/main/java/com/github/hoqhuuep/islandcraft/api/IslandGenerator.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.api; 2 | 3 | /** 4 | * Controls the distribution of biomes in an IslandCraft island. 5 | */ 6 | public interface IslandGenerator { 7 | /** 8 | * Returns an array of biomes for the whole island with the given dimensions 9 | * and random seed. 10 | * 11 | * @param xSize 12 | * the width of the island (measured in blocks) 13 | * @param zSize 14 | * the length of the island (measured in blocks) 15 | * @param islandSeed 16 | * the random seed of the island 17 | * @return an ICBiome[xSize * zSize] containing the biomes for the whole 18 | * island such that each element is at index [x + z * xSize] 19 | */ 20 | ICBiome[] generate(int xSize, int zSize, long islandSeed); 21 | } 22 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/IslandDatabase.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core; 2 | 3 | public interface IslandDatabase { 4 | static class Result { 5 | private final long islandSeed; 6 | private final String generator; 7 | 8 | public Result(final long islandSeed, final String generator) { 9 | this.islandSeed = islandSeed; 10 | this.generator = generator; 11 | } 12 | 13 | public long getIslandSeed() { 14 | return islandSeed; 15 | } 16 | 17 | public String getGenerator() { 18 | return generator; 19 | } 20 | } 21 | 22 | void save(String worldName, int centerX, int centerZ, long islandSeed, String generator); 23 | 24 | Result load(String worldName, int centerX, int centerZ); 25 | 26 | boolean isEmpty(String worldName); 27 | } 28 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/DefaultIslandCraft.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | import java.util.Map; 6 | import java.util.Set; 7 | 8 | import com.github.hoqhuuep.islandcraft.api.IslandCraft; 9 | import com.github.hoqhuuep.islandcraft.api.ICWorld; 10 | 11 | public class DefaultIslandCraft implements IslandCraft { 12 | private final Map worlds; 13 | 14 | public DefaultIslandCraft() { 15 | this.worlds = new HashMap(); 16 | } 17 | 18 | @Override 19 | public void addWorld(final ICWorld world) { 20 | worlds.put(world.getName(), world); 21 | } 22 | 23 | @Override 24 | public ICWorld getWorld(final String worldName) { 25 | return worlds.get(worldName); 26 | } 27 | 28 | @Override 29 | public Set getWorlds() { 30 | return new HashSet(worlds.values()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/ConstantBiomeDistribution.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core; 2 | 3 | import com.github.hoqhuuep.islandcraft.api.BiomeDistribution; 4 | import com.github.hoqhuuep.islandcraft.api.ICBiome; 5 | import com.github.hoqhuuep.islandcraft.util.StringUtils; 6 | 7 | public class ConstantBiomeDistribution implements BiomeDistribution { 8 | private final ICBiome biome; 9 | 10 | public ConstantBiomeDistribution(final String[] args) { 11 | ICLogger.logger.info("Creating ConstantBiomeDistribution with args: " + StringUtils.join(args, " ")); 12 | if (args.length != 1) { 13 | ICLogger.logger.error("ConstantBiomeDistribution requrires 1 parameter, " + args.length + " given"); 14 | throw new IllegalArgumentException("ConstantBiomeDistribution requrires 1 parameter"); 15 | } 16 | biome = ICBiome.valueOf(args[0]); 17 | } 18 | 19 | @Override 20 | public ICBiome biomeAt(final int x, final int z, final long worldSeed) { 21 | return biome; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | IslandCraft 2 | =========== 3 | 4 | IslandCraft is a Bukkit plugin which modifies the terrain generation to create an ocean with many islands. 5 | 6 | **BukkitDev**: http://dev.bukkit.org/bukkit-plugins/islandcraft/ 7 | 8 | **Sponge Forums**: https://forums.spongepowered.org/t/wip-islandcraft-generates-and-ocean-filled-with-biome-themed-islands/11522 9 | 10 | **Wiki**: https://github.com/hoqhuuep/IslandCraft/wiki 11 | 12 | ![Savanna](http://dev.bukkit.org/thumbman/images/71/269/200x112/2014-03-22_10.57.54.png.-m1.png) _ 13 | ![Plains](http://dev.bukkit.org/thumbman/images/71/267/200x112/2014-03-22_11.27.12.png.-m1.png) _ 14 | ![Mesa](http://dev.bukkit.org/thumbman/images/71/265/200x112/2014-03-22_11.15.40.png.-m1.png) 15 | 16 | ![Extreme Hills](http://dev.bukkit.org/thumbman/images/71/260/200x112/2014-03-22_11.33.43.png.-m1.png) _ 17 | ![Desert](http://dev.bukkit.org/thumbman/images/71/259/200x112/2014-03-22_11.18.50.png.-m1.png) _ 18 | ![Cold Taiga](http://dev.bukkit.org/thumbman/images/71/258/200x112/2014-03-22_11.30.18.png.-m1.png) 19 | -------------------------------------------------------------------------------- /IslandCraft-NMS/src/main/java/com/github/hoqhuuep/islandcraft/nms/NmsWrapper.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms; 2 | 3 | import org.bukkit.Server; 4 | import org.bukkit.World; 5 | 6 | public abstract class NmsWrapper { 7 | public static NmsWrapper getInstance(final Server server) { 8 | final String packageName = server.getClass().getPackage().getName(); 9 | final String version = packageName.substring(packageName.lastIndexOf('.') + 1); 10 | if (version.equals("craftbukkit")) { 11 | // Before renamed NMS 12 | return null; 13 | } 14 | try { 15 | final Class clazz = Class.forName(NmsWrapper.class.getPackage().getName() + "." + version + ".NmsHandler"); 16 | return (NmsWrapper) clazz.getConstructor().newInstance(); 17 | } catch (final Exception e) { 18 | // No support for this version 19 | return null; 20 | } 21 | } 22 | 23 | public abstract boolean installBiomeGenerator(World world, BiomeGenerator biomeGenerator); 24 | } 25 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_4_R1/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_4_R1/NmsHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_4_R1; 2 | 3 | import org.bukkit.World; 4 | import org.bukkit.craftbukkit.v1_4_R1.CraftWorld; 5 | 6 | import net.minecraft.server.v1_4_R1.WorldProvider; 7 | 8 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 9 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 10 | 11 | public class NmsHandler extends NmsWrapper { 12 | @Override 13 | public boolean installBiomeGenerator(final World world, final BiomeGenerator biomeGenerator) { 14 | if (!(world instanceof CraftWorld)) { 15 | // Wrong version? 16 | return false; 17 | } 18 | final CraftWorld craftWorld = (CraftWorld) world; 19 | final WorldProvider worldProvider = craftWorld.getHandle().worldProvider; 20 | if (worldProvider.d instanceof CustomWorldChunkManager) { 21 | // Already installed 22 | return false; 23 | } 24 | worldProvider.d = new CustomWorldChunkManager(biomeGenerator); 25 | return true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_5_R1/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_5_R1/NmsHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_5_R1; 2 | 3 | import org.bukkit.World; 4 | import org.bukkit.craftbukkit.v1_5_R1.CraftWorld; 5 | 6 | import net.minecraft.server.v1_5_R1.WorldProvider; 7 | 8 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 9 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 10 | 11 | public class NmsHandler extends NmsWrapper { 12 | @Override 13 | public boolean installBiomeGenerator(final World world, final BiomeGenerator biomeGenerator) { 14 | if (!(world instanceof CraftWorld)) { 15 | // Wrong version? 16 | return false; 17 | } 18 | final CraftWorld craftWorld = (CraftWorld) world; 19 | final WorldProvider worldProvider = craftWorld.getHandle().worldProvider; 20 | if (worldProvider.d instanceof CustomWorldChunkManager) { 21 | // Already installed 22 | return false; 23 | } 24 | worldProvider.d = new CustomWorldChunkManager(biomeGenerator); 25 | return true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_5_R2/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_5_R2/NmsHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_5_R2; 2 | 3 | import org.bukkit.World; 4 | import org.bukkit.craftbukkit.v1_5_R2.CraftWorld; 5 | 6 | import net.minecraft.server.v1_5_R2.WorldProvider; 7 | 8 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 9 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 10 | 11 | public class NmsHandler extends NmsWrapper { 12 | @Override 13 | public boolean installBiomeGenerator(final World world, final BiomeGenerator biomeGenerator) { 14 | if (!(world instanceof CraftWorld)) { 15 | // Wrong version? 16 | return false; 17 | } 18 | final CraftWorld craftWorld = (CraftWorld) world; 19 | final WorldProvider worldProvider = craftWorld.getHandle().worldProvider; 20 | if (worldProvider.d instanceof CustomWorldChunkManager) { 21 | // Already installed 22 | return false; 23 | } 24 | worldProvider.d = new CustomWorldChunkManager(biomeGenerator); 25 | return true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_5_R3/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_5_R3/NmsHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_5_R3; 2 | 3 | import org.bukkit.World; 4 | import org.bukkit.craftbukkit.v1_5_R3.CraftWorld; 5 | 6 | import net.minecraft.server.v1_5_R3.WorldProvider; 7 | 8 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 9 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 10 | 11 | public class NmsHandler extends NmsWrapper { 12 | @Override 13 | public boolean installBiomeGenerator(final World world, final BiomeGenerator biomeGenerator) { 14 | if (!(world instanceof CraftWorld)) { 15 | // Wrong version? 16 | return false; 17 | } 18 | final CraftWorld craftWorld = (CraftWorld) world; 19 | final WorldProvider worldProvider = craftWorld.getHandle().worldProvider; 20 | if (worldProvider.d instanceof CustomWorldChunkManager) { 21 | // Already installed 22 | return false; 23 | } 24 | worldProvider.d = new CustomWorldChunkManager(biomeGenerator); 25 | return true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_6_R1/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_6_R1/NmsHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_6_R1; 2 | 3 | import org.bukkit.World; 4 | import org.bukkit.craftbukkit.v1_6_R1.CraftWorld; 5 | 6 | import net.minecraft.server.v1_6_R1.WorldProvider; 7 | 8 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 9 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 10 | 11 | public class NmsHandler extends NmsWrapper { 12 | @Override 13 | public boolean installBiomeGenerator(final World world, final BiomeGenerator biomeGenerator) { 14 | if (!(world instanceof CraftWorld)) { 15 | // Wrong version? 16 | return false; 17 | } 18 | final CraftWorld craftWorld = (CraftWorld) world; 19 | final WorldProvider worldProvider = craftWorld.getHandle().worldProvider; 20 | if (worldProvider.e instanceof CustomWorldChunkManager) { 21 | // Already installed 22 | return false; 23 | } 24 | worldProvider.e = new CustomWorldChunkManager(biomeGenerator); 25 | return true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_6_R2/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_6_R2/NmsHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_6_R2; 2 | 3 | import org.bukkit.World; 4 | import org.bukkit.craftbukkit.v1_6_R2.CraftWorld; 5 | 6 | import net.minecraft.server.v1_6_R2.WorldProvider; 7 | 8 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 9 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 10 | 11 | public class NmsHandler extends NmsWrapper { 12 | @Override 13 | public boolean installBiomeGenerator(final World world, final BiomeGenerator biomeGenerator) { 14 | if (!(world instanceof CraftWorld)) { 15 | // Wrong version? 16 | return false; 17 | } 18 | final CraftWorld craftWorld = (CraftWorld) world; 19 | final WorldProvider worldProvider = craftWorld.getHandle().worldProvider; 20 | if (worldProvider.e instanceof CustomWorldChunkManager) { 21 | // Already installed 22 | return false; 23 | } 24 | worldProvider.e = new CustomWorldChunkManager(biomeGenerator); 25 | return true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_6_R3/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_6_R3/NmsHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_6_R3; 2 | 3 | import org.bukkit.World; 4 | import org.bukkit.craftbukkit.v1_6_R3.CraftWorld; 5 | 6 | import net.minecraft.server.v1_6_R3.WorldProvider; 7 | 8 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 9 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 10 | 11 | public class NmsHandler extends NmsWrapper { 12 | @Override 13 | public boolean installBiomeGenerator(final World world, final BiomeGenerator biomeGenerator) { 14 | if (!(world instanceof CraftWorld)) { 15 | // Wrong version? 16 | return false; 17 | } 18 | final CraftWorld craftWorld = (CraftWorld) world; 19 | final WorldProvider worldProvider = craftWorld.getHandle().worldProvider; 20 | if (worldProvider.e instanceof CustomWorldChunkManager) { 21 | // Already installed 22 | return false; 23 | } 24 | worldProvider.e = new CustomWorldChunkManager(biomeGenerator); 25 | return true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_7_R1/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_7_R1/NmsHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_7_R1; 2 | 3 | import org.bukkit.World; 4 | import org.bukkit.craftbukkit.v1_7_R1.CraftWorld; 5 | 6 | import net.minecraft.server.v1_7_R1.WorldProvider; 7 | 8 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 9 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 10 | 11 | public class NmsHandler extends NmsWrapper { 12 | @Override 13 | public boolean installBiomeGenerator(final World world, final BiomeGenerator biomeGenerator) { 14 | if (!(world instanceof CraftWorld)) { 15 | // Wrong version? 16 | return false; 17 | } 18 | final CraftWorld craftWorld = (CraftWorld) world; 19 | final WorldProvider worldProvider = craftWorld.getHandle().worldProvider; 20 | if (worldProvider.e instanceof CustomWorldChunkManager) { 21 | // Already installed 22 | return false; 23 | } 24 | worldProvider.e = new CustomWorldChunkManager(biomeGenerator); 25 | return true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_7_R2/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_7_R2/NmsHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_7_R2; 2 | 3 | import org.bukkit.World; 4 | import org.bukkit.craftbukkit.v1_7_R2.CraftWorld; 5 | 6 | import net.minecraft.server.v1_7_R2.WorldProvider; 7 | 8 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 9 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 10 | 11 | public class NmsHandler extends NmsWrapper { 12 | @Override 13 | public boolean installBiomeGenerator(final World world, final BiomeGenerator biomeGenerator) { 14 | if (!(world instanceof CraftWorld)) { 15 | // Wrong version? 16 | return false; 17 | } 18 | final CraftWorld craftWorld = (CraftWorld) world; 19 | final WorldProvider worldProvider = craftWorld.getHandle().worldProvider; 20 | if (worldProvider.e instanceof CustomWorldChunkManager) { 21 | // Already installed 22 | return false; 23 | } 24 | worldProvider.e = new CustomWorldChunkManager(biomeGenerator); 25 | return true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_7_R3/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_7_R3/NmsHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_7_R3; 2 | 3 | import org.bukkit.World; 4 | import org.bukkit.craftbukkit.v1_7_R3.CraftWorld; 5 | 6 | import net.minecraft.server.v1_7_R3.WorldProvider; 7 | 8 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 9 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 10 | 11 | public class NmsHandler extends NmsWrapper { 12 | @Override 13 | public boolean installBiomeGenerator(final World world, final BiomeGenerator biomeGenerator) { 14 | if (!(world instanceof CraftWorld)) { 15 | // Wrong version? 16 | return false; 17 | } 18 | final CraftWorld craftWorld = (CraftWorld) world; 19 | final WorldProvider worldProvider = craftWorld.getHandle().worldProvider; 20 | if (worldProvider.e instanceof CustomWorldChunkManager) { 21 | // Already installed 22 | return false; 23 | } 24 | worldProvider.e = new CustomWorldChunkManager(biomeGenerator); 25 | return true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_7_R4/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_7_R4/NmsHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_7_R4; 2 | 3 | import org.bukkit.World; 4 | import org.bukkit.craftbukkit.v1_7_R4.CraftWorld; 5 | 6 | import net.minecraft.server.v1_7_R4.WorldProvider; 7 | 8 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 9 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 10 | 11 | public class NmsHandler extends NmsWrapper { 12 | @Override 13 | public boolean installBiomeGenerator(final World world, final BiomeGenerator biomeGenerator) { 14 | if (!(world instanceof CraftWorld)) { 15 | // Wrong version? 16 | return false; 17 | } 18 | final CraftWorld craftWorld = (CraftWorld) world; 19 | final WorldProvider worldProvider = craftWorld.getHandle().worldProvider; 20 | if (worldProvider.e instanceof CustomWorldChunkManager) { 21 | // Already installed 22 | return false; 23 | } 24 | worldProvider.e = new CustomWorldChunkManager(biomeGenerator); 25 | return true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Daniel Simmons 4 | Copyright (c) contributors 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/EmptyIslandGenerator.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core; 2 | 3 | import com.github.hoqhuuep.islandcraft.api.ICBiome; 4 | import com.github.hoqhuuep.islandcraft.api.IslandGenerator; 5 | import com.github.hoqhuuep.islandcraft.util.StringUtils; 6 | 7 | public class EmptyIslandGenerator implements IslandGenerator { 8 | public EmptyIslandGenerator(final String[] args) { 9 | ICLogger.logger.info("Creating EmptyIslandGenerator with args: " + StringUtils.join(args, " ")); 10 | if (args.length != 0) { 11 | ICLogger.logger.error("EmptyIslandGenerator requrires 0 parameters, " + args.length + " given"); 12 | throw new IllegalArgumentException("EmptyIslandGenerator requrires 0 parameters, " + args.length + " given"); 13 | } 14 | } 15 | 16 | @Override 17 | public ICBiome[] generate(final int xSize, final int zSize, final long islandSeed) { 18 | ICLogger.logger.info(String.format("Generating island from EmptyIslandGenerator with xSize: %d, zSize: %d, islandSeed: %d", xSize, zSize, islandSeed)); 19 | return new ICBiome[xSize * zSize]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/mosaic/Grid.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core.mosaic; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public final class Grid { 7 | private final List>> grid; 8 | 9 | public Grid(final int xRows, final int zRows) { 10 | grid = new ArrayList>>(xRows); 11 | for (int x = 0; x < xRows; ++x) { 12 | final List> row = new ArrayList>(zRows); 13 | for (int z = 0; z < zRows; ++z) { 14 | row.add(new ArrayList()); 15 | } 16 | grid.add(row); 17 | } 18 | } 19 | 20 | public void add(final int xRow, final int zRow, final T item) { 21 | grid.get(xRow).get(zRow).add(item); 22 | } 23 | 24 | public List getRegion(final int xMin, final int zMin, final int xMax, final int zMax) { 25 | final List result = new ArrayList(); 26 | for (int x = xMin; x < xMax; ++x) { 27 | for (int z = zMin; z < zMax; ++z) { 28 | result.addAll(grid.get(x).get(z)); 29 | } 30 | } 31 | return result; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/mosaic/AngleComparator.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core.mosaic; 2 | 3 | import java.util.Comparator; 4 | 5 | public class AngleComparator implements Comparator { 6 | private final Site base; 7 | private final Site zero; 8 | 9 | public AngleComparator(final Site base, final Site zero) { 10 | this.zero = zero; 11 | this.base = sub(base, zero); 12 | } 13 | 14 | @Override 15 | public final int compare(final Site p1, final Site p2) { 16 | return Double.compare(angle(base, sub(p1, zero)), angle(base, sub(p2, zero))); 17 | } 18 | 19 | public static Site sub(final Site p1, final Site p2) { 20 | return new Site(p1.x - p2.x, p1.z - p2.z); 21 | } 22 | 23 | private static double angle(final Site p1, final Site p2) { 24 | return (Math.atan2(cross(p1, p2), dot(p1, p2)) + (Math.PI * 2)) % (Math.PI * 2); 25 | } 26 | 27 | private static double cross(final Site p1, final Site p2) { 28 | return p1.x * p2.z - p1.z * p2.x; 29 | } 30 | 31 | private static double dot(final Site p1, final Site p2) { 32 | return p1.x * p2.x + p1.z * p2.z; 33 | } 34 | } -------------------------------------------------------------------------------- /IslandCraft-NMS/src/main/java/com/github/hoqhuuep/islandcraft/nms/BiomeGenerator.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms; 2 | 3 | import com.github.hoqhuuep.islandcraft.api.ICBiome; 4 | 5 | public abstract class BiomeGenerator { 6 | /** 7 | * Determines which biomes should be used for world generation for the given 8 | * chunk. Result must be a Biome[256] for the 16x16 area of the chunk. 9 | * 10 | * @param x 11 | * X-coordinate of the chunk 12 | * @param z 13 | * Z-coordinate of the chunk 14 | * @return Biome[256] containing biomes for each location in the chunk 15 | */ 16 | public abstract ICBiome[] generateChunkBiomes(int x, int z); 17 | 18 | /** 19 | * Determines which biome should used for world generation at the given 20 | * coordinates. 21 | * 22 | * @param x 23 | * X-coordinate for the biome 24 | * @param z 25 | * Z-coordinate for the biome 26 | * @return Biome for the location 27 | */ 28 | public abstract ICBiome generateBiome(int x, int z); 29 | 30 | /** 31 | * Called by the server every tick. Can be used to occasionally clean up old 32 | * data from a cache if needed. 33 | */ 34 | public abstract void cleanupCache(); 35 | } 36 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/ConstantIslandGenerator.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core; 2 | 3 | import java.util.Arrays; 4 | 5 | import com.github.hoqhuuep.islandcraft.api.ICBiome; 6 | import com.github.hoqhuuep.islandcraft.api.IslandGenerator; 7 | import com.github.hoqhuuep.islandcraft.util.StringUtils; 8 | 9 | public class ConstantIslandGenerator implements IslandGenerator { 10 | private final ICBiome biome; 11 | 12 | public ConstantIslandGenerator(final String[] args) { 13 | ICLogger.logger.info("Creating ConstantIslandGenerator with args: " + StringUtils.join(args, " ")); 14 | if (args.length != 1) { 15 | ICLogger.logger.error("ConstantIslandGenerator requrires 1 parameter, " + args.length + " given"); 16 | throw new IllegalArgumentException("ConstantIslandGenerator requrires 1 parameter, " + args.length + " given"); 17 | } 18 | biome = ICBiome.valueOf(args[0]); 19 | } 20 | 21 | @Override 22 | public ICBiome[] generate(final int xSize, final int zSize, final long islandSeed) { 23 | ICLogger.logger.info(String.format("Generating island from ConstantIslandGenerator with xSize: %d, zSize: %d, islandSeed: %d, biome: %s", xSize, zSize, islandSeed, biome)); 24 | final ICBiome[] result = new ICBiome[xSize * zSize]; 25 | Arrays.fill(result, biome); 26 | return result; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /IslandCraft-Sponge/src/main/java/com/github/hoqhuuep/islandcraft/IslandCraftGeneratorModifier.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft; 2 | 3 | import org.spongepowered.api.data.DataContainer; 4 | import org.spongepowered.api.world.WorldCreationSettings; 5 | import org.spongepowered.api.world.gen.BiomeGenerator; 6 | import org.spongepowered.api.world.gen.WorldGenerator; 7 | import org.spongepowered.api.world.gen.WorldGeneratorModifier; 8 | 9 | import com.github.hoqhuuep.islandcraft.core.IslandDatabase; 10 | 11 | import ninja.leaping.configurate.commented.CommentedConfigurationNode; 12 | 13 | public class IslandCraftGeneratorModifier implements WorldGeneratorModifier { 14 | private final CommentedConfigurationNode config; 15 | private final IslandDatabase database; 16 | 17 | public IslandCraftGeneratorModifier(CommentedConfigurationNode config, IslandDatabase database) { 18 | this.config = config; 19 | this.database = database; 20 | } 21 | 22 | @Override 23 | public String getId() { 24 | return "islandcraft:biomes"; 25 | } 26 | 27 | @Override 28 | public String getName() { 29 | return "IslandCraft Biomes"; 30 | } 31 | 32 | @Override 33 | public void modifyWorldGenerator(WorldCreationSettings world, DataContainer settings, WorldGenerator worldGenerator) { 34 | String worldName = world.getWorldName(); 35 | BiomeGenerator islandCraftBiomeGenerator = new IslandCraftBiomeGenerator(worldName, world.getSeed(), config.getNode(worldName), database); 36 | worldGenerator.setBiomeGenerator(islandCraftBiomeGenerator); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/EmptyIslandDistribution.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | import com.github.hoqhuuep.islandcraft.api.ICLocation; 7 | import com.github.hoqhuuep.islandcraft.api.ICRegion; 8 | import com.github.hoqhuuep.islandcraft.api.IslandDistribution; 9 | import com.github.hoqhuuep.islandcraft.util.StringUtils; 10 | 11 | public class EmptyIslandDistribution implements IslandDistribution { 12 | public EmptyIslandDistribution(final String[] args) { 13 | ICLogger.logger.info("Creating EmptyIslandDistribution with args: " + StringUtils.join(args, " ")); 14 | if (args.length != 0) { 15 | ICLogger.logger.error("EmptyIslandDistribution requrires 0 parameters, " + args.length + " given"); 16 | throw new IllegalArgumentException("EmptyIslandDistribution requrires 0 parameters, " + args.length + " given"); 17 | } 18 | } 19 | 20 | @Override 21 | public ICLocation getCenterAt(final int x, final int z, final long worldSeed) { 22 | return null; 23 | } 24 | 25 | @Override 26 | public Set getCentersAt(final int x, final int z, final long worldSeed) { 27 | return new HashSet(0); 28 | } 29 | 30 | @Override 31 | public ICRegion getInnerRegion(final ICLocation center, final long worldSeed) { 32 | return null; 33 | } 34 | 35 | @Override 36 | public ICRegion getOuterRegion(final ICLocation center, final long worldSeed) { 37 | return null; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /IslandCraft-API/src/main/java/com/github/hoqhuuep/islandcraft/api/ICLocation.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.api; 2 | 3 | /** 4 | * Represents a location in a world. 5 | */ 6 | public class ICLocation { 7 | private final int x; 8 | private final int z; 9 | 10 | /** 11 | * Creates an immutable ICLocation. 12 | * 13 | * @param x 14 | * x-coordinate of this location (measured in blocks) 15 | * @param z 16 | * z-coordinate of this location (measured in blocks) 17 | */ 18 | public ICLocation(final int x, final int z) { 19 | this.x = x; 20 | this.z = z; 21 | } 22 | 23 | /** 24 | * Returns the x-coordinate of this location (measured in blocks). 25 | */ 26 | public int getX() { 27 | return x; 28 | } 29 | 30 | /** 31 | * Returns the z-coordinate of this location (measured in blocks). 32 | */ 33 | public int getZ() { 34 | return z; 35 | } 36 | 37 | @Override 38 | public int hashCode() { 39 | final int prime = 31; 40 | int result = 1; 41 | result = prime * result + x; 42 | result = prime * result + z; 43 | return result; 44 | } 45 | 46 | @Override 47 | public boolean equals(final Object obj) { 48 | if (this == obj) 49 | return true; 50 | if (obj == null) 51 | return false; 52 | if (getClass() != obj.getClass()) 53 | return false; 54 | final ICLocation other = (ICLocation) obj; 55 | if (x != other.x) 56 | return false; 57 | if (z != other.z) 58 | return false; 59 | return true; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /IslandCraft-API/src/main/java/com/github/hoqhuuep/islandcraft/api/ICBiome.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.api; 2 | 3 | /** 4 | * Represents a Minecraft biome. 5 | * 6 | * In versions previous to 1.7, sensible backups are used for biomes which were 7 | * introduced later. For example ROOFED_FOREST will be replaced by FOREST and 8 | * DEEP_OCEAN will be replaced by OCEAN. 9 | */ 10 | public enum ICBiome { 11 | BEACH, 12 | BIRCH_FOREST, 13 | BIRCH_FOREST_HILLS, 14 | BIRCH_FOREST_HILLS_M, 15 | BIRCH_FOREST_M, 16 | COLD_BEACH, 17 | COLD_TAIGA, 18 | COLD_TAIGA_HILLS, 19 | COLD_TAIGA_M, 20 | DEEP_OCEAN, 21 | DESERT, 22 | DESERT_HILLS, 23 | DESERT_M, 24 | END, 25 | EXTREME_HILLS, 26 | EXTREME_HILLS_EDGE, 27 | EXTREME_HILLS_M, 28 | EXTREME_HILLS_PLUS, 29 | EXTREME_HILLS_PLUS_M, 30 | FLOWER_FOREST, 31 | FOREST, 32 | FOREST_HILLS, 33 | FROZEN_OCEAN, 34 | FROZEN_RIVER, 35 | ICE_MOUNTAINS, 36 | ICE_PLAINS, 37 | ICE_PLAINS_SPIKES, 38 | JUNGLE, 39 | JUNGLE_EDGE, 40 | JUNGLE_HILLS, 41 | JUNGLE_M, 42 | JUNGLE_EDGE_M, 43 | MEGA_SPRUCE_TAIGA, 44 | MEGA_SPRUCE_TAIGA_HILLS, 45 | MEGA_TAIGA, 46 | MEGA_TAIGA_HILLS, 47 | MESA, 48 | MESA_BRYCE, 49 | MESA_PLATEAU, 50 | MESA_PLATEAU_F, 51 | MESA_PLATEAU_F_M, 52 | MESA_PLATEAU_M, 53 | MUSHROOM_ISLAND, 54 | MUSHROOM_ISLAND_SHORE, 55 | NETHER, 56 | OCEAN, 57 | PLAINS, 58 | RIVER, 59 | ROOFED_FOREST, 60 | ROOFED_FOREST_M, 61 | SAVANNA, 62 | SAVANNA_M, 63 | SAVANNA_PLATEAU, 64 | SAVANNA_PLATEAU_M, 65 | STONE_BEACH, 66 | SUNFLOWER_PLAINS, 67 | SWAMPLAND, 68 | SWAMPLAND_M, 69 | TAIGA, 70 | TAIGA_HILLS, 71 | TAIGA_M; 72 | } 73 | -------------------------------------------------------------------------------- /IslandCraft-Bukkit/src/main/java/com/github/hoqhuuep/islandcraft/bukkit/IslandCraftBiomeGenerator.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.bukkit; 2 | 3 | import java.util.Arrays; 4 | 5 | import com.github.hoqhuuep.islandcraft.api.ICBiome; 6 | import com.github.hoqhuuep.islandcraft.api.ICWorld; 7 | import com.github.hoqhuuep.islandcraft.core.ICLogger; 8 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 9 | 10 | public class IslandCraftBiomeGenerator extends BiomeGenerator { 11 | private final ICWorld world; 12 | 13 | public IslandCraftBiomeGenerator(final ICWorld world) { 14 | this.world = world; 15 | } 16 | 17 | @Override 18 | public ICBiome generateBiome(final int x, final int z) { 19 | try { 20 | return world.getBiomeAt(x, z); 21 | } catch (final Exception e) { 22 | ICLogger.logger.warning(String.format("Error generating biome for position with x: %d, z: %d", x, z)); 23 | ICLogger.logger.warning("Default biome 'DEEP_OCEAN' used instead"); 24 | ICLogger.logger.warning("Exception message: " + e.getMessage()); 25 | return ICBiome.DEEP_OCEAN; 26 | } 27 | } 28 | 29 | @Override 30 | public ICBiome[] generateChunkBiomes(final int x, final int z) { 31 | try { 32 | return world.getBiomeChunk(x, z); 33 | } catch (final Exception e) { 34 | ICLogger.logger.warning(String.format("Error generating biomes for chunk with x: %d, z: %d", x, z)); 35 | ICLogger.logger.warning("Default biome 'DEEP_OCEAN' used instead"); 36 | ICLogger.logger.warning("Exception message: " + e.getMessage()); 37 | final ICBiome[] result = new ICBiome[256]; 38 | Arrays.fill(result, ICBiome.DEEP_OCEAN); 39 | return result; 40 | } 41 | } 42 | 43 | @Override 44 | public void cleanupCache() { 45 | // Nothing to do 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /IslandCraft-API/src/main/java/com/github/hoqhuuep/islandcraft/api/ICRegion.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.api; 2 | 3 | /** 4 | * Represents a rectangular region in a world. 5 | */ 6 | public class ICRegion { 7 | private final ICLocation min; 8 | private final ICLocation max; 9 | 10 | /** 11 | * Creates an immutable ICRegion. 12 | * 13 | * @param min 14 | * the minimum x and z coordinates of this region 15 | * @param max 16 | * the maximum x and z coordinates of this region 17 | */ 18 | public ICRegion(final ICLocation min, final ICLocation max) { 19 | this.min = min; 20 | this.max = max; 21 | } 22 | 23 | /** 24 | * Returns the minimum x and z coordinates of this region 25 | */ 26 | public ICLocation getMin() { 27 | return min; 28 | } 29 | 30 | /** 31 | * Returns the maximum x and z coordinates of this region 32 | */ 33 | public ICLocation getMax() { 34 | return max; 35 | } 36 | 37 | @Override 38 | public int hashCode() { 39 | final int prime = 31; 40 | int result = 1; 41 | result = prime * result + ((max == null) ? 0 : max.hashCode()); 42 | result = prime * result + ((min == null) ? 0 : min.hashCode()); 43 | return result; 44 | } 45 | 46 | @Override 47 | public boolean equals(Object obj) { 48 | if (this == obj) 49 | return true; 50 | if (obj == null) 51 | return false; 52 | if (getClass() != obj.getClass()) 53 | return false; 54 | ICRegion other = (ICRegion) obj; 55 | if (max == null) { 56 | if (other.max != null) 57 | return false; 58 | } else if (!max.equals(other.max)) 59 | return false; 60 | if (min == null) { 61 | if (other.min != null) 62 | return false; 63 | } else if (!min.equals(other.min)) 64 | return false; 65 | return true; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_8_R1/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_8_R1/NmsHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_8_R1; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import org.bukkit.World; 6 | import org.bukkit.craftbukkit.v1_8_R1.CraftWorld; 7 | 8 | import net.minecraft.server.v1_8_R1.WorldProvider; 9 | 10 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 11 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 12 | 13 | public class NmsHandler extends NmsWrapper { 14 | 15 | @Override 16 | public boolean installBiomeGenerator(final World world, final BiomeGenerator biomeGenerator) { 17 | if (!(world instanceof CraftWorld)) { 18 | // Wrong version? 19 | return false; 20 | } 21 | final CraftWorld craftWorld = (CraftWorld) world; 22 | final WorldProvider worldProvider = craftWorld.getHandle().worldProvider; 23 | try { 24 | Field field = getField(worldProvider.getClass(), "c"); 25 | field.setAccessible(true); 26 | if (field.get(worldProvider) instanceof CustomWorldChunkManager) { 27 | // Already installed 28 | return false; 29 | } 30 | field.set(worldProvider, new CustomWorldChunkManager(biomeGenerator)); 31 | return true; 32 | } catch (NoSuchFieldException e) { 33 | return false; 34 | } catch (IllegalArgumentException e) { 35 | return false; 36 | } catch (IllegalAccessException e) { 37 | return false; 38 | } 39 | } 40 | 41 | private static Field getField(Class clazz, String fieldName) throws NoSuchFieldException { 42 | try { 43 | return clazz.getDeclaredField(fieldName); 44 | } catch (NoSuchFieldException e) { 45 | Class superClass = clazz.getSuperclass(); 46 | if (superClass == null) { 47 | throw e; 48 | } else { 49 | return getField(superClass, fieldName); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_8_R2/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_8_R2/NmsHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_8_R2; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import org.bukkit.World; 6 | import org.bukkit.craftbukkit.v1_8_R2.CraftWorld; 7 | 8 | import net.minecraft.server.v1_8_R2.WorldProvider; 9 | 10 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 11 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 12 | 13 | public class NmsHandler extends NmsWrapper { 14 | 15 | @Override 16 | public boolean installBiomeGenerator(final World world, final BiomeGenerator biomeGenerator) { 17 | if (!(world instanceof CraftWorld)) { 18 | // Wrong version? 19 | return false; 20 | } 21 | final CraftWorld craftWorld = (CraftWorld) world; 22 | final WorldProvider worldProvider = craftWorld.getHandle().worldProvider; 23 | try { 24 | Field field = getField(worldProvider.getClass(), "c"); 25 | field.setAccessible(true); 26 | if (field.get(worldProvider) instanceof CustomWorldChunkManager) { 27 | // Already installed 28 | return false; 29 | } 30 | field.set(worldProvider, new CustomWorldChunkManager(biomeGenerator)); 31 | return true; 32 | } catch (NoSuchFieldException e) { 33 | return false; 34 | } catch (IllegalArgumentException e) { 35 | return false; 36 | } catch (IllegalAccessException e) { 37 | return false; 38 | } 39 | } 40 | 41 | private static Field getField(Class clazz, String fieldName) throws NoSuchFieldException { 42 | try { 43 | return clazz.getDeclaredField(fieldName); 44 | } catch (NoSuchFieldException e) { 45 | Class superClass = clazz.getSuperclass(); 46 | if (superClass == null) { 47 | throw e; 48 | } else { 49 | return getField(superClass, fieldName); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_8_R3/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_8_R3/NmsHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_8_R3; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import org.bukkit.World; 6 | import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; 7 | 8 | import net.minecraft.server.v1_8_R3.WorldProvider; 9 | 10 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 11 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 12 | 13 | public class NmsHandler extends NmsWrapper { 14 | 15 | @Override 16 | public boolean installBiomeGenerator(final World world, final BiomeGenerator biomeGenerator) { 17 | if (!(world instanceof CraftWorld)) { 18 | // Wrong version? 19 | return false; 20 | } 21 | final CraftWorld craftWorld = (CraftWorld) world; 22 | final WorldProvider worldProvider = craftWorld.getHandle().worldProvider; 23 | try { 24 | Field field = getField(worldProvider.getClass(), "c"); 25 | field.setAccessible(true); 26 | if (field.get(worldProvider) instanceof CustomWorldChunkManager) { 27 | // Already installed 28 | return false; 29 | } 30 | field.set(worldProvider, new CustomWorldChunkManager(biomeGenerator)); 31 | return true; 32 | } catch (NoSuchFieldException e) { 33 | return false; 34 | } catch (IllegalArgumentException e) { 35 | return false; 36 | } catch (IllegalAccessException e) { 37 | return false; 38 | } 39 | } 40 | 41 | private static Field getField(Class clazz, String fieldName) throws NoSuchFieldException { 42 | try { 43 | return clazz.getDeclaredField(fieldName); 44 | } catch (NoSuchFieldException e) { 45 | Class superClass = clazz.getSuperclass(); 46 | if (superClass == null) { 47 | throw e; 48 | } else { 49 | return getField(superClass, fieldName); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_9_R1/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_9_R1/NmsHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_9_R1; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import org.bukkit.World; 6 | import org.bukkit.craftbukkit.v1_9_R1.CraftWorld; 7 | 8 | import net.minecraft.server.v1_9_R1.WorldProvider; 9 | 10 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 11 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 12 | 13 | public class NmsHandler extends NmsWrapper { 14 | 15 | @Override 16 | public boolean installBiomeGenerator(final World world, final BiomeGenerator biomeGenerator) { 17 | if (!(world instanceof CraftWorld)) { 18 | // Wrong version? 19 | return false; 20 | } 21 | final CraftWorld craftWorld = (CraftWorld) world; 22 | final WorldProvider worldProvider = craftWorld.getHandle().worldProvider; 23 | try { 24 | Field field = getField(worldProvider.getClass(), "c"); 25 | field.setAccessible(true); 26 | if (field.get(worldProvider) instanceof CustomWorldChunkManager) { 27 | // Already installed 28 | return false; 29 | } 30 | field.set(worldProvider, new CustomWorldChunkManager(biomeGenerator)); 31 | return true; 32 | } catch (NoSuchFieldException e) { 33 | return false; 34 | } catch (IllegalArgumentException e) { 35 | return false; 36 | } catch (IllegalAccessException e) { 37 | return false; 38 | } 39 | } 40 | 41 | private static Field getField(Class clazz, String fieldName) throws NoSuchFieldException { 42 | try { 43 | return clazz.getDeclaredField(fieldName); 44 | } catch (NoSuchFieldException e) { 45 | Class superClass = clazz.getSuperclass(); 46 | if (superClass == null) { 47 | throw e; 48 | } else { 49 | return getField(superClass, fieldName); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_9_R2/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_9_R2/NmsHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_9_R2; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import org.bukkit.World; 6 | import org.bukkit.craftbukkit.v1_9_R2.CraftWorld; 7 | 8 | import net.minecraft.server.v1_9_R2.WorldProvider; 9 | 10 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 11 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 12 | 13 | public class NmsHandler extends NmsWrapper { 14 | 15 | @Override 16 | public boolean installBiomeGenerator(final World world, final BiomeGenerator biomeGenerator) { 17 | if (!(world instanceof CraftWorld)) { 18 | // Wrong version? 19 | return false; 20 | } 21 | final CraftWorld craftWorld = (CraftWorld) world; 22 | final WorldProvider worldProvider = craftWorld.getHandle().worldProvider; 23 | try { 24 | Field field = getField(worldProvider.getClass(), "c"); 25 | field.setAccessible(true); 26 | if (field.get(worldProvider) instanceof CustomWorldChunkManager) { 27 | // Already installed 28 | return false; 29 | } 30 | field.set(worldProvider, new CustomWorldChunkManager(biomeGenerator)); 31 | return true; 32 | } catch (NoSuchFieldException e) { 33 | return false; 34 | } catch (IllegalArgumentException e) { 35 | return false; 36 | } catch (IllegalAccessException e) { 37 | return false; 38 | } 39 | } 40 | 41 | private static Field getField(Class clazz, String fieldName) throws NoSuchFieldException { 42 | try { 43 | return clazz.getDeclaredField(fieldName); 44 | } catch (NoSuchFieldException e) { 45 | Class superClass = clazz.getSuperclass(); 46 | if (superClass == null) { 47 | throw e; 48 | } else { 49 | return getField(superClass, fieldName); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_10_R1/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_10_R1/NmsHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_10_R1; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import org.bukkit.World; 6 | import org.bukkit.craftbukkit.v1_10_R1.CraftWorld; 7 | 8 | import net.minecraft.server.v1_10_R1.WorldProvider; 9 | 10 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 11 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 12 | 13 | public class NmsHandler extends NmsWrapper { 14 | 15 | @Override 16 | public boolean installBiomeGenerator(final World world, final BiomeGenerator biomeGenerator) { 17 | if (!(world instanceof CraftWorld)) { 18 | // Wrong version? 19 | return false; 20 | } 21 | final CraftWorld craftWorld = (CraftWorld) world; 22 | final WorldProvider worldProvider = craftWorld.getHandle().worldProvider; 23 | try { 24 | Field field = getField(worldProvider.getClass(), "c"); 25 | field.setAccessible(true); 26 | if (field.get(worldProvider) instanceof CustomWorldChunkManager) { 27 | // Already installed 28 | return false; 29 | } 30 | field.set(worldProvider, new CustomWorldChunkManager(biomeGenerator)); 31 | return true; 32 | } catch (NoSuchFieldException e) { 33 | return false; 34 | } catch (IllegalArgumentException e) { 35 | return false; 36 | } catch (IllegalAccessException e) { 37 | return false; 38 | } 39 | } 40 | 41 | private static Field getField(Class clazz, String fieldName) throws NoSuchFieldException { 42 | try { 43 | return clazz.getDeclaredField(fieldName); 44 | } catch (NoSuchFieldException e) { 45 | Class superClass = clazz.getSuperclass(); 46 | if (superClass == null) { 47 | throw e; 48 | } else { 49 | return getField(superClass, fieldName); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_11_R1/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_11_R1/NmsHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_11_R1; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import org.bukkit.World; 6 | import org.bukkit.craftbukkit.v1_11_R1.CraftWorld; 7 | 8 | import net.minecraft.server.v1_11_R1.WorldProvider; 9 | 10 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 11 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 12 | 13 | public class NmsHandler extends NmsWrapper { 14 | 15 | @Override 16 | public boolean installBiomeGenerator(final World world, final BiomeGenerator biomeGenerator) { 17 | if (!(world instanceof CraftWorld)) { 18 | // Wrong version? 19 | return false; 20 | } 21 | final CraftWorld craftWorld = (CraftWorld) world; 22 | final WorldProvider worldProvider = craftWorld.getHandle().worldProvider; 23 | try { 24 | Field field = getField(worldProvider.getClass(), "c"); 25 | field.setAccessible(true); 26 | if (field.get(worldProvider) instanceof CustomWorldChunkManager) { 27 | // Already installed 28 | return false; 29 | } 30 | field.set(worldProvider, new CustomWorldChunkManager(biomeGenerator)); 31 | return true; 32 | } catch (NoSuchFieldException e) { 33 | return false; 34 | } catch (IllegalArgumentException e) { 35 | return false; 36 | } catch (IllegalAccessException e) { 37 | return false; 38 | } 39 | } 40 | 41 | private static Field getField(Class clazz, String fieldName) throws NoSuchFieldException { 42 | try { 43 | return clazz.getDeclaredField(fieldName); 44 | } catch (NoSuchFieldException e) { 45 | Class superClass = clazz.getSuperclass(); 46 | if (superClass == null) { 47 | throw e; 48 | } else { 49 | return getField(superClass, fieldName); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_12_R1/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_12_R1/NmsHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_12_R1; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import org.bukkit.World; 6 | import org.bukkit.craftbukkit.v1_12_R1.CraftWorld; 7 | 8 | import net.minecraft.server.v1_12_R1.WorldProvider; 9 | 10 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 11 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 12 | 13 | public class NmsHandler extends NmsWrapper { 14 | 15 | @Override 16 | public boolean installBiomeGenerator(final World world, final BiomeGenerator biomeGenerator) { 17 | if (!(world instanceof CraftWorld)) { 18 | // Wrong version? 19 | return false; 20 | } 21 | final CraftWorld craftWorld = (CraftWorld) world; 22 | final WorldProvider worldProvider = craftWorld.getHandle().worldProvider; 23 | try { 24 | Field field = getField(worldProvider.getClass(), "c"); 25 | field.setAccessible(true); 26 | if (field.get(worldProvider) instanceof CustomWorldChunkManager) { 27 | // Already installed 28 | return false; 29 | } 30 | field.set(worldProvider, new CustomWorldChunkManager(biomeGenerator)); 31 | return true; 32 | } catch (NoSuchFieldException e) { 33 | return false; 34 | } catch (IllegalArgumentException e) { 35 | return false; 36 | } catch (IllegalAccessException e) { 37 | return false; 38 | } 39 | } 40 | 41 | private static Field getField(Class clazz, String fieldName) throws NoSuchFieldException { 42 | try { 43 | return clazz.getDeclaredField(fieldName); 44 | } catch (NoSuchFieldException e) { 45 | Class superClass = clazz.getSuperclass(); 46 | if (superClass == null) { 47 | throw e; 48 | } else { 49 | return getField(superClass, fieldName); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/mosaic/RangeList.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core.mosaic; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Random; 6 | 7 | public final class RangeList { 8 | public static final double TWO_PI = Math.PI * 2; 9 | public static final double EPSILON = 1.0 / 256.0; 10 | private final List ranges; 11 | 12 | public RangeList() { 13 | ranges = new ArrayList(); 14 | ranges.add(new RangeEntry(0, TWO_PI)); 15 | } 16 | 17 | public void subtract(final double min, final double max) { 18 | if (min > TWO_PI) { 19 | subtract(min - TWO_PI, max - TWO_PI); 20 | } else if (max < 0) { 21 | subtract(min + TWO_PI, max + TWO_PI); 22 | } else if (min < 0) { 23 | subtract(0, max); 24 | subtract(min + TWO_PI, TWO_PI); 25 | } else if (max > TWO_PI) { 26 | subtract(min, TWO_PI); 27 | subtract(0, max - TWO_PI); 28 | } else { 29 | for (int i = 0; i < ranges.size(); ++i) { 30 | final RangeEntry range = ranges.get(i); 31 | if (min < range.min + EPSILON) { 32 | if (max > range.max - EPSILON) { 33 | ranges.remove(i--); 34 | } else if (max > range.min) { 35 | range.min = max; 36 | } else { 37 | break; 38 | } 39 | } else if (min < range.max) { 40 | if (max > range.max - EPSILON) { 41 | range.max = min; 42 | } else { 43 | ranges.add(i++, new RangeEntry(range.min, min)); 44 | range.min = max; 45 | break; 46 | } 47 | } 48 | } 49 | } 50 | } 51 | 52 | public boolean isEmpty() { 53 | return ranges.isEmpty(); 54 | } 55 | 56 | public double random(final Random random) { 57 | final RangeEntry range = ranges.get(random.nextInt(ranges.size())); 58 | return range.min + random.nextDouble() * (range.max - range.min); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/util/ExpiringLoadingCache.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.util; 2 | 3 | import java.util.HashMap; 4 | import java.util.Iterator; 5 | import java.util.Map; 6 | import java.util.Map.Entry; 7 | import java.util.Random; 8 | import java.util.Timer; 9 | import java.util.TimerTask; 10 | 11 | public class ExpiringLoadingCache implements Cache { 12 | private final int millis; 13 | private final CacheLoader loader; 14 | private final Map> cache = new HashMap>(); 15 | private final Random random = new Random(); 16 | 17 | public ExpiringLoadingCache(int seconds, CacheLoader loader) { 18 | this.millis = seconds * 1000; 19 | this.loader = loader; 20 | startTimer(); 21 | } 22 | 23 | private void startTimer() { 24 | Timer timer = new Timer(); 25 | timer.schedule(new TimerTask() { 26 | @Override 27 | public void run() { 28 | removeExpired(); 29 | startTimer(); 30 | } 31 | }, millis + random.nextInt(millis)); 32 | } 33 | 34 | private void removeExpired() { 35 | long nanos = System.nanoTime(); 36 | Iterator>> iterator = cache.entrySet().iterator(); 37 | while (iterator.hasNext()) { 38 | Entry> value = iterator.next(); 39 | if (value.getValue().expired(nanos)) { 40 | iterator.remove(); 41 | } 42 | } 43 | } 44 | 45 | @Override 46 | public V get(K key) { 47 | // Try to get value from cache 48 | Expiring value = cache.get(key); 49 | if (value == null) { 50 | // Otherwise generate new value using loader 51 | value = new Expiring(millis, loader.load(key)); 52 | cache.put(key, value); 53 | } 54 | return value.access(); 55 | } 56 | 57 | private static class Expiring { 58 | private long lifeNanos; 59 | private long expiryNanos; 60 | private final V value; 61 | 62 | public Expiring(long millis, V value) { 63 | this.lifeNanos = millis * 1000 * 1000; 64 | this.expiryNanos = System.nanoTime() + lifeNanos; 65 | this.value = value; 66 | } 67 | 68 | public V access() { 69 | this.expiryNanos = System.nanoTime() + lifeNanos; 70 | return this.value; 71 | } 72 | 73 | public boolean expired(long nanos) { 74 | return nanos > expiryNanos; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/IslandCache.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core; 2 | 3 | import com.github.hoqhuuep.islandcraft.api.ICBiome; 4 | import com.github.hoqhuuep.islandcraft.api.ICIsland; 5 | import com.github.hoqhuuep.islandcraft.util.Cache; 6 | import com.github.hoqhuuep.islandcraft.util.CacheLoader; 7 | import com.github.hoqhuuep.islandcraft.util.ExpiringLoadingCache; 8 | 9 | public class IslandCache { 10 | private final Cache cache; 11 | 12 | public IslandCache() { 13 | cache = new ExpiringLoadingCache(30, new IslandCacheLoader()); 14 | } 15 | 16 | public ICBiome biomeAt(final ICIsland island, final int relativeX, final int relativeZ) { 17 | final ICBiome[] biomes = cache.get(island); 18 | final int xSize = island.getInnerRegion().getMax().getZ() - island.getInnerRegion().getMin().getZ(); 19 | return biomes[relativeZ * xSize + relativeX]; 20 | } 21 | 22 | private static final int BLOCKS_PER_CHUNK = 16; 23 | 24 | public ICBiome[] biomeChunk(final ICIsland island, final int relativeX, final int relativeZ) { 25 | final int xSize = island.getInnerRegion().getMax().getZ() - island.getInnerRegion().getMin().getZ(); 26 | final ICBiome[] result = new ICBiome[BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK]; 27 | final ICBiome[] biomes = cache.get(island); 28 | for (int z = 0; z < BLOCKS_PER_CHUNK; ++z) { 29 | System.arraycopy(biomes, xSize * (relativeZ + z) + relativeX, result, z * BLOCKS_PER_CHUNK, BLOCKS_PER_CHUNK); 30 | } 31 | return result; 32 | } 33 | 34 | public ICBiome[] biomeAll(final ICIsland island) { 35 | return cache.get(island).clone(); 36 | } 37 | 38 | private static class IslandCacheLoader implements CacheLoader { 39 | @Override 40 | public ICBiome[] load(final ICIsland island) { 41 | final int xSize = island.getInnerRegion().getMax().getX() - island.getInnerRegion().getMin().getX(); 42 | final int zSize = island.getInnerRegion().getMax().getZ() - island.getInnerRegion().getMin().getZ(); 43 | final long islandSeed = island.getSeed(); 44 | return island.getGenerator().generate(xSize, zSize, islandSeed); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /IslandCraft-API/src/main/java/com/github/hoqhuuep/islandcraft/api/IslandDistribution.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.api; 2 | 3 | import java.util.Set; 4 | 5 | /** 6 | * Controls the distribution of islands in an IslandCraft world. 7 | */ 8 | public interface IslandDistribution { 9 | /** 10 | * Returns the location of the center of the island whose inner-region 11 | * contains the given location. 12 | * 13 | * @param x 14 | * the x-coordinate of the location to check (measured in blocks) 15 | * @param z 16 | * the z-coordinate of the location to check (measured in blocks) 17 | * @param worldSeed 18 | * the random seed of the world 19 | * @return the center of the island or null if the given location is in the 20 | * ocean 21 | */ 22 | ICLocation getCenterAt(int x, int z, long worldSeed); 23 | 24 | /** 25 | * Returns a set containing the locations of the centers of the islands 26 | * whose outer-regions contain the given location. 27 | * 28 | * @param x 29 | * the x-coordinate of the location to check (measured in blocks) 30 | * @param z 31 | * the z-coordinate of the location to check (measured in blocks) 32 | * @param worldSeed 33 | * the random seed of the world 34 | * @return a set containing the centers of the islands 35 | */ 36 | Set getCentersAt(int x, int z, long worldSeed); 37 | 38 | /** 39 | * Returns the inner-region of the island whose center is given. 40 | * 41 | * @param center 42 | * the location of the center of the island 43 | * @param worldSeed 44 | * the random seed of the world 45 | * @return the inner-region of the island or null if there is no such island 46 | */ 47 | ICRegion getInnerRegion(ICLocation center, long worldSeed); 48 | 49 | /** 50 | * Returns the outer-region of the island whose center is given. 51 | * 52 | * @param center 53 | * the location of the center of the island 54 | * @param worldSeed 55 | * the random seed of the world 56 | * @return the outer-region of the island or null if there is no such island 57 | */ 58 | ICRegion getOuterRegion(ICLocation center, long worldSeed); 59 | } 60 | -------------------------------------------------------------------------------- /IslandCraft-Bukkit/src/main/java/com/github/hoqhuuep/islandcraft/bukkit/BukkitWorldConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.bukkit; 2 | 3 | import java.util.List; 4 | 5 | import org.bukkit.configuration.ConfigurationSection; 6 | 7 | import com.github.hoqhuuep.islandcraft.core.ICWorldConfig; 8 | import com.github.hoqhuuep.islandcraft.core.ICLogger; 9 | 10 | public class BukkitWorldConfig implements ICWorldConfig { 11 | private final String worldName; 12 | private final ConfigurationSection config; 13 | 14 | public BukkitWorldConfig(String worldName, ConfigurationSection config) { 15 | this.worldName = worldName; 16 | this.config = config; 17 | } 18 | 19 | @Override 20 | public String getOcean() { 21 | if (!config.contains("ocean") || !config.isString("ocean")) { 22 | ICLogger.logger.warning("No string-value for 'worlds." + worldName + ".ocean' found in config.yml"); 23 | ICLogger.logger.warning("Default value 'com.github.hoqhuuep.islandcraft.core.ConstantBiomeDistribution DEEP_OCEAN' will be used"); 24 | } 25 | return config.getString("ocean", "com.github.hoqhuuep.islandcraft.core.ConstantBiomeDistribution DEEP_OCEAN"); 26 | } 27 | 28 | @Override 29 | public String getIslandDistribution() { 30 | if (!config.contains("island-distribution") || !config.isString("island-distribution")) { 31 | ICLogger.logger.warning("No string-value for 'worlds." + worldName + ".island-distribution' found in config.yml"); 32 | ICLogger.logger.warning("Default value 'com.github.hoqhuuep.islandcraft.core.EmptyIslandDistribution' will be used"); 33 | } 34 | return config.getString("island-distribution", "com.github.hoqhuuep.islandcraft.core.EmptyIslandDistribution"); 35 | } 36 | 37 | @Override 38 | public String[] getIslandGenerstors() { 39 | if (!config.contains("island-generators") || !config.isList("island-generators")) { 40 | ICLogger.logger.warning("No list-value for 'worlds." + worldName + ".island-generators' found in config.yml"); 41 | ICLogger.logger.warning("Default value '[com.github.hoqhuuep.islandcraft.core.EmptyIslandGenerator]' will be used"); 42 | } 43 | List islandGenerators = config.getStringList("island-generators"); 44 | if (islandGenerators.isEmpty()) { 45 | islandGenerators.add("com.github.hoqhuuep.islandcraft.core.EmptyIslandGenerator"); 46 | } 47 | return islandGenerators.toArray(new String[islandGenerators.size()]); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /IslandCraft-API/src/main/java/com/github/hoqhuuep/islandcraft/api/ICIsland.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.api; 2 | 3 | /** 4 | * Represents an island in an IslandCraft world. 5 | */ 6 | public interface ICIsland { 7 | /** 8 | * Returns the random seed used to generate this island. 9 | */ 10 | long getSeed(); 11 | 12 | /** 13 | * Returns the IslandGenerator used to generate this island. 14 | */ 15 | IslandGenerator getGenerator(); 16 | 17 | /** 18 | * Returns the location of the center of this island. 19 | */ 20 | ICLocation getCenter(); 21 | 22 | /** 23 | * Returns the region of this island which does not overlap with neighboring 24 | * islands. 25 | */ 26 | ICRegion getInnerRegion(); 27 | 28 | /** 29 | * Returns the region of this island including the ocean overlapping with 30 | * neighboring islands. 31 | */ 32 | ICRegion getOuterRegion(); 33 | 34 | /** 35 | * Returns the biome which will be generated at the given location. 36 | * 37 | * @param relativeLocation 38 | * location relative to this island (must be less than xSize) 39 | * @return the biome which will be generated 40 | */ 41 | ICBiome getBiomeAt(ICLocation relativeLocation); 42 | 43 | /** 44 | * Returns the biome which will be generated at the given location. 45 | * 46 | * @param relativeX 47 | * location relative to this island (must be less than xSize) 48 | * @param relativeZ 49 | * location relative to this island (must be less than zSize) 50 | * @return the biome which will be generated 51 | */ 52 | ICBiome getBiomeAt(int relativeX, int relativeZ); 53 | 54 | /** 55 | * Returns the biomes for a whole chunk. 56 | * 57 | * @param relativeLocation 58 | * location of the chunk relative to the island 59 | * @return an ICBiome[16 * 16] containing the biomes for the whole chunk 60 | * such that each element is at index [x + z * 16] 61 | */ 62 | ICBiome[] getBiomeChunk(ICLocation relativeLocation); 63 | 64 | /** 65 | * Returns the biomes for a whole chunk. 66 | * 67 | * @param relativeX 68 | * location of the chunk relative to the island 69 | * @param relativeZ 70 | * location of the chunk relative to the island 71 | * @return an ICBiome[16 * 16] containing the biomes for the whole chunk 72 | * such that each element is at index [x + z * 16] 73 | */ 74 | ICBiome[] getBiomeChunk(int relativeX, int relativeZ); 75 | 76 | /** 77 | * Returns the biomes for the whole island. 78 | * 79 | * @return an ICBiome[xSize * zSize] containing the biomes for the whole 80 | * island such that each element is at index [x + z * xSize] 81 | */ 82 | ICBiome[] getBiomeAll(); 83 | } 84 | -------------------------------------------------------------------------------- /IslandCraft-Sponge/src/main/java/com/github/hoqhuuep/islandcraft/IslandCraftPlugin.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft; 2 | 3 | import java.io.IOException; 4 | import java.sql.SQLException; 5 | 6 | import org.slf4j.Logger; 7 | import org.spongepowered.api.Sponge; 8 | import org.spongepowered.api.config.DefaultConfig; 9 | import org.spongepowered.api.event.Listener; 10 | import org.spongepowered.api.event.game.state.GameInitializationEvent; 11 | import org.spongepowered.api.event.game.state.GameStoppedEvent; 12 | import org.spongepowered.api.plugin.Plugin; 13 | import org.spongepowered.api.service.sql.SqlService; 14 | import org.spongepowered.api.world.gen.WorldGeneratorModifier; 15 | 16 | import com.github.hoqhuuep.islandcraft.core.ICLogger; 17 | import com.github.hoqhuuep.islandcraft.core.IslandDatabase; 18 | import com.google.inject.Inject; 19 | 20 | import ninja.leaping.configurate.ConfigurationOptions; 21 | import ninja.leaping.configurate.commented.CommentedConfigurationNode; 22 | import ninja.leaping.configurate.loader.ConfigurationLoader; 23 | 24 | @Plugin(id = "islandcraft", name = "IslandCraft", version = "1.0.8") 25 | public class IslandCraftPlugin { 26 | @Inject 27 | private Logger logger; 28 | 29 | @Inject 30 | @DefaultConfig(sharedRoot = false) 31 | private ConfigurationLoader configLoader; 32 | 33 | private CommentedConfigurationNode config; 34 | 35 | @Listener 36 | public void onGameInitialization(GameInitializationEvent event) throws IOException, SQLException { 37 | // Logging 38 | ICLogger.logger = new Slf4jLogger(logger); 39 | 40 | // Metrics 41 | // https://github.com/Hidendra/Plugin-Metrics/wiki/Usage 42 | try { 43 | Metrics metrics = new Metrics(Sponge.getGame(), Sponge.getPluginManager().fromInstance(this).get()); 44 | metrics.start(); 45 | } catch (final Exception e) { 46 | ICLogger.logger.warning("Failed to start MCStats"); 47 | } 48 | 49 | // Configuration 50 | config = configLoader.load(ConfigurationOptions.defaults().setShouldCopyDefaults(true)); 51 | if (!"1.0.0".equals(config.getNode("config-version").setComment("Do not modify config-version").getString("1.0.0"))) { 52 | logger.error("Invalid config-version found in './config/islandcraft/islandcraft.config'. Must be '1.0.0'."); 53 | return; 54 | } 55 | 56 | // Database 57 | SqlService sqlService = Sponge.getServiceManager().provide(SqlService.class).get(); 58 | IslandDatabase database = new JdbcIslandDatabase(sqlService, config.getNode("database")); 59 | 60 | // Modify world generator 61 | WorldGeneratorModifier islandCraftGeneratorModifier = new IslandCraftGeneratorModifier(config.getNode("worlds"), database); 62 | Sponge.getRegistry().register(WorldGeneratorModifier.class, islandCraftGeneratorModifier); 63 | } 64 | 65 | @Listener 66 | public void onGameStopped(GameStoppedEvent event) throws IOException { 67 | if (config != null) { 68 | configLoader.save(config); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /IslandCraft-Bukkit/src/main/resources/config.yml: -------------------------------------------------------------------------------- 1 | # Do not modify config-version 2 | config-version: 1.0.0 3 | # If verbose-logging is false only warnings and errors will be logged 4 | verbose-logging: false 5 | # Same available options as database settings in bukkit.yml 6 | # http://wiki.bukkit.org/Bukkit.yml#database 7 | database: 8 | driver: org.sqlite.JDBC 9 | url: jdbc:sqlite:{DIR}{NAME}.db 10 | username: bukkit 11 | password: walrus 12 | isolation: SERIALIZABLE 13 | worlds: 14 | # By default IslandCraft is enabled on "world_islandcraft". 15 | # You can change the world name here or even add more than one world 16 | world_islandcraft: 17 | # There is currently only 1 option for ocean-generator. Please use: 18 | # com.github.hoqhuuep.islandcraft.core.ConstantBiomeDistribution 19 | ocean: com.github.hoqhuuep.islandcraft.core.ConstantBiomeDistribution DEEP_OCEAN 20 | # There are currently 3 options for island-distribution. Please use one of: 21 | # com.github.hoqhuuep.islandcraft.core.HexagonalIslandDistribution 22 | # com.github.hoqhuuep.islandcraft.core.SquareIslandDistribution 23 | # com.github.hoqhuuep.islandcraft.core.EmptyIslandDistribution 24 | island-distribution: com.github.hoqhuuep.islandcraft.core.HexagonalIslandDistribution 288 32 25 | # There is currently 2 options for island-generators. Please use one of: 26 | # com.github.hoqhuuep.islandcraft.core.ConstantIslandGenerator 27 | # com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha 28 | island-generators: 29 | - com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha BIRCH_FOREST BIRCH_FOREST_M BIRCH_FOREST_HILLS BIRCH_FOREST_HILLS_M ~ ~ OCEAN BEACH RIVER 30 | - com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha COLD_TAIGA COLD_TAIGA_M COLD_TAIGA_HILLS ~ ~ ~ OCEAN COLD_BEACH FROZEN_RIVER 31 | - com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha DESERT DESERT_M DESERT_HILLS ~ ~ ~ OCEAN BEACH RIVER 32 | - com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha EXTREME_HILLS EXTREME_HILLS_M EXTREME_HILLS_PLUS EXTREME_HILLS_PLUS_M EXTREME_HILLS_EDGE ~ OCEAN STONE_BEACH RIVER 33 | - com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha FOREST ~ FOREST_HILLS ~ FLOWER_FOREST ~ OCEAN BEACH RIVER 34 | - com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha ICE_PLAINS ~ ICE_MOUNTAINS ~ ICE_PLAINS_SPIKES ~ OCEAN FROZEN_OCEAN FROZEN_RIVER 35 | - com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha JUNGLE JUNGLE_M JUNGLE_HILLS ~ JUNGLE_EDGE JUNGLE_EDGE_M OCEAN BEACH RIVER 36 | - com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha MEGA_TAIGA MEGA_SPRUCE_TAIGA MEGA_TAIGA_HILLS MEGA_SPRUCE_TAIGA_HILLS ~ ~ OCEAN BEACH RIVER 37 | - com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha MESA MESA_BRYCE MESA_PLATEAU MESA_PLATEAU_M MESA_PLATEAU_F MESA_PLATEAU_F_M OCEAN MESA RIVER 38 | - com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha MUSHROOM_ISLAND ~ ~ ~ ~ ~ OCEAN MUSHROOM_ISLAND_SHORE RIVER 39 | - com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha PLAINS ~ SUNFLOWER_PLAINS ~ ~ ~ OCEAN BEACH RIVER 40 | - com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha ROOFED_FOREST ROOFED_FOREST_M ~ ~ ~ ~ OCEAN BEACH RIVER 41 | - com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha SAVANNA SAVANNA_M SAVANNA_PLATEAU SAVANNA_PLATEAU_M ~ ~ OCEAN BEACH RIVER 42 | - com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha SWAMPLAND SWAMPLAND_M ~ ~ ~ ~ OCEAN BEACH RIVER 43 | - com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha TAIGA TAIGA_M TAIGA_HILLS ~ ~ ~ OCEAN BEACH RIVER 44 | -------------------------------------------------------------------------------- /IslandCraft-API/src/main/java/com/github/hoqhuuep/islandcraft/api/ICWorld.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.api; 2 | 3 | import java.util.Set; 4 | 5 | /** 6 | * Represents an IslandCraft world. 7 | */ 8 | public interface ICWorld { 9 | /** 10 | * Returns the random seed used to generate this world (as specified in 11 | * server.properties). 12 | */ 13 | long getSeed(); 14 | 15 | /** 16 | * Returns the name of this world. 17 | */ 18 | String getName(); 19 | 20 | /** 21 | * Returns the biome which will be generated at the given location. 22 | * 23 | * @param location 24 | * location in the world 25 | * @return the biome which will be generated 26 | */ 27 | ICBiome getBiomeAt(ICLocation location); 28 | 29 | /** 30 | * Returns the biome which will be generated at the given location. 31 | * 32 | * @param x 33 | * the x-coordinate of the location in the world (measured in 34 | * blocks) 35 | * @param z 36 | * the z-coordinate of the location in the world (measured in 37 | * blocks) 38 | * @return the biome which will be generated 39 | */ 40 | ICBiome getBiomeAt(int x, int z); 41 | 42 | /** 43 | * Returns the biomes for a whole chunk. 44 | * 45 | * @param location 46 | * location of the chunk in the world 47 | * @return an ICBiome[16 * 16] containing the biomes for the whole chunk 48 | * such that each element is at index [x + z * 16] 49 | */ 50 | ICBiome[] getBiomeChunk(ICLocation location); 51 | 52 | /** 53 | * Returns the biomes for a whole chunk. 54 | * 55 | * @param x 56 | * location of the chunk in the world (measured in blocks) 57 | * @param z 58 | * location of the chunk in the world (measured in blocks) 59 | * @return an ICBiome[16 * 16] containing the biomes for the whole chunk 60 | * such that each element is at index [x + z * 16] 61 | */ 62 | ICBiome[] getBiomeChunk(int x, int z); 63 | 64 | /** 65 | * Returns the island whose inner-region contains the given location. 66 | * 67 | * @param location 68 | * the location to check 69 | * @return the island or null if the given location is in the ocean 70 | */ 71 | ICIsland getIslandAt(ICLocation location); 72 | 73 | /** 74 | * Returns the island whose inner-region contains the given location. 75 | * 76 | * @param x 77 | * the x-coordinate of the location to check (measured in blocks) 78 | * @param z 79 | * the z-coordinate of the location to check (measured in blocks) 80 | * @return the island or null if the given location is in the ocean 81 | */ 82 | ICIsland getIslandAt(int x, int z); 83 | 84 | /** 85 | * Returns a set containing the islands whose outer-regions contain the 86 | * given location. 87 | * 88 | * @param location 89 | * the location to check 90 | * @return a set containing the centers of the islands 91 | */ 92 | Set getIslandsAt(ICLocation location); 93 | 94 | /** 95 | * Returns a set containing the islands whose outer-regions contain the 96 | * given location. 97 | * 98 | * @param x 99 | * the x-coordinate of the location to check (measured in blocks) 100 | * @param z 101 | * the z-coordinate of the location to check (measured in blocks) 102 | * @return a set containing the centers of the islands 103 | */ 104 | Set getIslandsAt(int x, int z); 105 | } 106 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/ICClassLoader.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core; 2 | 3 | import java.lang.reflect.Constructor; 4 | import java.util.Arrays; 5 | 6 | import com.github.hoqhuuep.islandcraft.api.BiomeDistribution; 7 | import com.github.hoqhuuep.islandcraft.api.IslandDistribution; 8 | import com.github.hoqhuuep.islandcraft.api.IslandGenerator; 9 | import com.github.hoqhuuep.islandcraft.util.Cache; 10 | import com.github.hoqhuuep.islandcraft.util.CacheLoader; 11 | import com.github.hoqhuuep.islandcraft.util.EternalLoadingCache; 12 | 13 | public class ICClassLoader { 14 | private final Cache islandDistributionCache; 15 | private final Cache islandGeneratorCache; 16 | private final Cache biomeDistributionCache; 17 | 18 | public ICClassLoader() { 19 | islandDistributionCache = new EternalLoadingCache(new StringConstructorCacheLoader()); 20 | islandGeneratorCache = new EternalLoadingCache(new StringConstructorCacheLoader()); 21 | biomeDistributionCache = new EternalLoadingCache(new StringConstructorCacheLoader()); 22 | } 23 | 24 | public IslandDistribution getIslandDistribution(final String string) { 25 | try { 26 | return islandDistributionCache.get(string); 27 | } catch (final Exception e) { 28 | ICLogger.logger.warning("Error creating IslandDistribution from string: " + string); 29 | ICLogger.logger.warning("Using 'com.github.hoqhuuep.islandcraft.core.EmptyIslandDistribution' instead"); 30 | return new EmptyIslandDistribution(new String[0]); 31 | } 32 | } 33 | 34 | public IslandGenerator getIslandGenerator(final String string) { 35 | try { 36 | return islandGeneratorCache.get(string); 37 | } catch (final Exception e) { 38 | ICLogger.logger.warning("Error creating IslandGenerator from string: " + string); 39 | ICLogger.logger.warning("Using 'com.github.hoqhuuep.islandcraft.core.EmptyIslandGenerator' instead"); 40 | return new EmptyIslandGenerator(new String[0]); 41 | } 42 | } 43 | 44 | public BiomeDistribution getBiomeDistribution(final String string) { 45 | try { 46 | return biomeDistributionCache.get(string); 47 | } catch (final Exception e) { 48 | ICLogger.logger.warning("Error creating BiomeDistribution from string: " + string); 49 | ICLogger.logger.warning("Using 'com.github.hoqhuuep.islandcraft.core.ConstantBiomeDistribution DEEP_OCEAN' instead"); 50 | return new ConstantBiomeDistribution(new String[] { "DEEP_OCEAN" }); 51 | } 52 | } 53 | 54 | private static class StringConstructorCacheLoader implements CacheLoader { 55 | @Override 56 | @SuppressWarnings("unchecked") 57 | public T load(final String string) { 58 | ICLogger.logger.info("Creating instance of class with string: " + string); 59 | try { 60 | final String[] split = string.split(" "); 61 | final String className = split[0]; 62 | final String[] args = Arrays.copyOfRange(split, 1, split.length); 63 | final Class subClass = Class.forName(className); 64 | final Constructor constructor = subClass.getConstructor(String[].class); 65 | return (T) constructor.newInstance(new Object[] { args }); 66 | } catch (final Exception e) { 67 | throw new RuntimeException("Failed to create instance of " + string, e); 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /IslandCraft-Sponge/src/main/java/com/github/hoqhuuep/islandcraft/SpongeWorldConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | import com.github.hoqhuuep.islandcraft.core.ICWorldConfig; 7 | import com.google.common.reflect.TypeToken; 8 | 9 | import ninja.leaping.configurate.commented.CommentedConfigurationNode; 10 | import ninja.leaping.configurate.objectmapping.ObjectMappingException; 11 | 12 | public class SpongeWorldConfig implements ICWorldConfig { 13 | private final CommentedConfigurationNode config; 14 | private static final String DEFAULT_OCEAN = "com.github.hoqhuuep.islandcraft.core.ConstantBiomeDistribution DEEP_OCEAN"; 15 | private static final String DEFAULT_ISLAND_DISTRIBUTION = "com.github.hoqhuuep.islandcraft.core.HexagonalIslandDistribution 288 32"; 16 | private static final String[] DEFAULT_ISLAND_GENERATORS = new String[] { 17 | "com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha BIRCH_FOREST BIRCH_FOREST_M BIRCH_FOREST_HILLS BIRCH_FOREST_HILLS_M ~ ~ OCEAN BEACH RIVER", 18 | "com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha COLD_TAIGA COLD_TAIGA_M COLD_TAIGA_HILLS ~ ~ ~ OCEAN COLD_BEACH FROZEN_RIVER", 19 | "com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha DESERT DESERT_M DESERT_HILLS ~ ~ ~ OCEAN BEACH RIVER", 20 | "com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha EXTREME_HILLS EXTREME_HILLS_M EXTREME_HILLS_PLUS EXTREME_HILLS_PLUS_M EXTREME_HILLS_EDGE ~ OCEAN STONE_BEACH RIVER", 21 | "com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha FOREST ~ FOREST_HILLS ~ FLOWER_FOREST ~ OCEAN BEACH RIVER", 22 | "com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha ICE_PLAINS ~ ICE_MOUNTAINS ~ ICE_PLAINS_SPIKES ~ OCEAN FROZEN_OCEAN FROZEN_RIVER", 23 | "com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha JUNGLE JUNGLE_M JUNGLE_HILLS ~ JUNGLE_EDGE JUNGLE_EDGE_M OCEAN BEACH RIVER", 24 | "com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha MEGA_TAIGA MEGA_SPRUCE_TAIGA MEGA_TAIGA_HILLS MEGA_SPRUCE_TAIGA_HILLS ~ ~ OCEAN BEACH RIVER", 25 | "com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha MESA MESA_BRYCE MESA_PLATEAU MESA_PLATEAU_M MESA_PLATEAU_F MESA_PLATEAU_F_M OCEAN MESA RIVER", 26 | "com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha MUSHROOM_ISLAND ~ ~ ~ ~ ~ OCEAN MUSHROOM_ISLAND_SHORE RIVER", 27 | "com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha PLAINS ~ SUNFLOWER_PLAINS ~ ~ ~ OCEAN BEACH RIVER", 28 | "com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha ROOFED_FOREST ROOFED_FOREST_M ~ ~ ~ ~ OCEAN BEACH RIVER", 29 | "com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha SAVANNA SAVANNA_M SAVANNA_PLATEAU SAVANNA_PLATEAU_M ~ ~ OCEAN BEACH RIVER", 30 | "com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha SWAMPLAND SWAMPLAND_M ~ ~ ~ ~ OCEAN BEACH RIVER", 31 | "com.github.hoqhuuep.islandcraft.core.IslandGeneratorAlpha TAIGA TAIGA_M TAIGA_HILLS ~ ~ ~ OCEAN BEACH RIVER" 32 | }; 33 | 34 | public SpongeWorldConfig(CommentedConfigurationNode config) { 35 | this.config = config; 36 | } 37 | 38 | @Override 39 | public String getOcean() { 40 | return config.getNode("ocean").getString(DEFAULT_OCEAN); 41 | } 42 | 43 | @Override 44 | public String getIslandDistribution() { 45 | return config.getNode("island-distribution").getString(DEFAULT_ISLAND_DISTRIBUTION); 46 | } 47 | 48 | @Override 49 | public String[] getIslandGenerstors() { 50 | try { 51 | List defaultGenerators = Arrays.asList(DEFAULT_ISLAND_GENERATORS); 52 | List list = config.getNode("island-generators").getList(TypeToken.of(String.class), defaultGenerators); 53 | if (list.isEmpty()) { 54 | config.getNode("island-generators").setValue(defaultGenerators); 55 | return DEFAULT_ISLAND_GENERATORS; 56 | } 57 | return list.toArray(new String[list.size()]); 58 | } catch (ObjectMappingException e) { 59 | e.printStackTrace(); 60 | return DEFAULT_ISLAND_GENERATORS; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/DefaultIsland.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core; 2 | 3 | import com.github.hoqhuuep.islandcraft.api.ICBiome; 4 | import com.github.hoqhuuep.islandcraft.api.ICIsland; 5 | import com.github.hoqhuuep.islandcraft.api.ICLocation; 6 | import com.github.hoqhuuep.islandcraft.api.ICRegion; 7 | import com.github.hoqhuuep.islandcraft.api.IslandGenerator; 8 | 9 | public class DefaultIsland implements ICIsland { 10 | private final IslandCache cache; 11 | private final IslandGenerator generator; 12 | private final ICLocation center; 13 | private final ICRegion innerRegion; 14 | private final ICRegion outerRegion; 15 | private final long seed; 16 | 17 | public DefaultIsland(final ICRegion innerRegion, final ICRegion outerRegion, final long seed, final IslandGenerator generator, final IslandCache cache) { 18 | this.cache = cache; 19 | this.seed = seed; 20 | this.generator = generator; 21 | final int centerX = (innerRegion.getMin().getX() + innerRegion.getMax().getX()) / 2; 22 | final int centerZ = (innerRegion.getMin().getZ() + innerRegion.getMax().getZ()) / 2; 23 | this.center = new ICLocation(centerX, centerZ); 24 | this.innerRegion = innerRegion; 25 | this.outerRegion = outerRegion; 26 | } 27 | 28 | @Override 29 | public long getSeed() { 30 | return seed; 31 | } 32 | 33 | @Override 34 | public ICLocation getCenter() { 35 | return center; 36 | } 37 | 38 | @Override 39 | public ICRegion getInnerRegion() { 40 | return innerRegion; 41 | } 42 | 43 | @Override 44 | public ICRegion getOuterRegion() { 45 | return outerRegion; 46 | } 47 | 48 | @Override 49 | public ICBiome getBiomeAt(final ICLocation relativeLocation) { 50 | return getBiomeAt(relativeLocation.getX(), relativeLocation.getZ()); 51 | } 52 | 53 | @Override 54 | public ICBiome getBiomeAt(final int relativeX, final int relativeZ) { 55 | return cache.biomeAt(this, relativeX, relativeZ); 56 | } 57 | 58 | @Override 59 | public ICBiome[] getBiomeChunk(ICLocation relativeLocation) { 60 | return getBiomeChunk(relativeLocation.getX(), relativeLocation.getZ()); 61 | } 62 | 63 | @Override 64 | public ICBiome[] getBiomeChunk(int relativeX, int relativeZ) { 65 | return cache.biomeChunk(this, relativeX, relativeZ); 66 | } 67 | 68 | @Override 69 | public ICBiome[] getBiomeAll() { 70 | return cache.biomeAll(this); 71 | } 72 | 73 | @Override 74 | public IslandGenerator getGenerator() { 75 | return generator; 76 | } 77 | 78 | @Override 79 | public int hashCode() { 80 | final int prime = 31; 81 | int result = 1; 82 | result = prime * result + ((generator == null) ? 0 : generator.hashCode()); 83 | result = prime * result + ((innerRegion == null) ? 0 : innerRegion.hashCode()); 84 | result = prime * result + ((outerRegion == null) ? 0 : outerRegion.hashCode()); 85 | result = prime * result + (int) (seed ^ (seed >>> 32)); 86 | return result; 87 | } 88 | 89 | @Override 90 | public boolean equals(Object obj) { 91 | if (this == obj) 92 | return true; 93 | if (obj == null) 94 | return false; 95 | if (getClass() != obj.getClass()) 96 | return false; 97 | DefaultIsland other = (DefaultIsland) obj; 98 | if (generator == null) { 99 | if (other.generator != null) 100 | return false; 101 | } else if (!generator.equals(other.generator)) 102 | return false; 103 | if (innerRegion == null) { 104 | if (other.innerRegion != null) 105 | return false; 106 | } else if (!innerRegion.equals(other.innerRegion)) 107 | return false; 108 | if (outerRegion == null) { 109 | if (other.outerRegion != null) 110 | return false; 111 | } else if (!outerRegion.equals(other.outerRegion)) 112 | return false; 113 | if (seed != other.seed) 114 | return false; 115 | return true; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /IslandCraft-Sponge/src/main/java/com/github/hoqhuuep/islandcraft/JdbcIslandDatabase.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft; 2 | 3 | import java.sql.Connection; 4 | import java.sql.PreparedStatement; 5 | import java.sql.ResultSet; 6 | import java.sql.SQLException; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import org.spongepowered.api.service.sql.SqlService; 11 | 12 | import com.github.hoqhuuep.islandcraft.core.IslandDatabase; 13 | 14 | import ninja.leaping.configurate.commented.CommentedConfigurationNode; 15 | 16 | public class JdbcIslandDatabase implements IslandDatabase { 17 | private final DataSource dataSource; 18 | private final String username; 19 | private final String password; 20 | 21 | public JdbcIslandDatabase(SqlService sqlService, CommentedConfigurationNode config) throws SQLException { 22 | String url = config.getNode("url").getString("jdbc:h2:./islandcraft"); 23 | username = config.getNode("username").getString(null); 24 | password = config.getNode("password").getString(null); 25 | dataSource = sqlService.getDataSource(url); 26 | createTablesIfTheyDoNotExist(); 27 | } 28 | 29 | Connection getConnection() throws SQLException { 30 | if (username != null && password != null) { 31 | return dataSource.getConnection(username, password); 32 | } 33 | return dataSource.getConnection(); 34 | } 35 | 36 | private void createTablesIfTheyDoNotExist() throws SQLException { 37 | try (Connection connection = getConnection(); 38 | PreparedStatement statement = connection.prepareStatement("CREATE TABLE IF NOT EXISTS islandcraft_core (world_name VARCHAR(255) NOT NULL, center_x INTEGER NOT NULL, center_z INTEGER NOT NULL, island_seed BIGINT, generator VARCHAR(65535))")) { 39 | statement.executeUpdate(); 40 | } 41 | } 42 | 43 | @Override 44 | public void save(String worldName, int centerX, int centerZ, long islandSeed, String generator) { 45 | if (load(worldName, centerX, centerZ) != null) { 46 | // Already exists => UPDATE 47 | try (Connection connection = getConnection(); 48 | PreparedStatement statement = connection.prepareStatement("UPDATE islandcraft_core SET island_seed=?, generator=? WHERE world_name=? AND center_x=? AND center_z=?")) { 49 | statement.setLong(1, islandSeed); 50 | statement.setString(2, generator); 51 | statement.setString(3, worldName); 52 | statement.setInt(4, centerX); 53 | statement.setInt(5, centerZ); 54 | statement.executeUpdate(); 55 | } catch (SQLException e) { 56 | // Nothing we can do about this... 57 | e.printStackTrace(); 58 | } 59 | } else { 60 | // Does not already exist => INSERT 61 | try (Connection connection = getConnection(); 62 | PreparedStatement statement = connection.prepareStatement("INSERT INTO islandcraft_core (world_name, center_x, center_z, island_seed, generator) VALUES (?, ?, ?, ?, ?)")) { 63 | statement.setString(1, worldName); 64 | statement.setInt(2, centerX); 65 | statement.setInt(3, centerZ); 66 | statement.setLong(4, islandSeed); 67 | statement.setString(5, generator); 68 | statement.executeUpdate(); 69 | } catch (SQLException e) { 70 | // Nothing we can do about this... 71 | e.printStackTrace(); 72 | } 73 | } 74 | } 75 | 76 | @Override 77 | public Result load(String worldName, int centerX, int centerZ) { 78 | try (Connection connection = getConnection(); 79 | PreparedStatement statement = connection.prepareStatement("SELECT island_seed, generator FROM islandcraft_core WHERE world_name=? AND center_x=? AND center_z=?")) { 80 | statement.setString(1, worldName); 81 | statement.setInt(2, centerX); 82 | statement.setInt(3, centerZ); 83 | try (ResultSet result = statement.executeQuery()) { 84 | if (result.next()) { 85 | long islandSeed = result.getLong(1); 86 | String generator = result.getString(2); 87 | return new Result(islandSeed, generator); 88 | } 89 | } 90 | } catch (SQLException e) { 91 | // Nothing we can do about this... 92 | e.printStackTrace(); 93 | } 94 | return null; 95 | } 96 | 97 | @Override 98 | public boolean isEmpty(String worldName) { 99 | try (Connection connection = getConnection(); 100 | PreparedStatement statement = connection.prepareStatement("SELECT COUNT(*) FROM islandcraft_core WHERE world_name=?")) { 101 | statement.setString(1, worldName); 102 | try (ResultSet result = statement.executeQuery()) { 103 | if (result.next()) { 104 | return result.getInt(1) == 0; 105 | } 106 | } 107 | } catch (SQLException e) { 108 | // Nothing we can do about this... 109 | e.printStackTrace(); 110 | } 111 | return false; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /IslandCraft-Bukkit/src/main/java/com/github/hoqhuuep/islandcraft/bukkit/BiomeGeneratorListener.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.bukkit; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | import org.bukkit.Chunk; 7 | import org.bukkit.World; 8 | import org.bukkit.configuration.ConfigurationSection; 9 | import org.bukkit.event.EventHandler; 10 | import org.bukkit.event.Listener; 11 | import org.bukkit.event.world.ChunkLoadEvent; 12 | import org.bukkit.event.world.WorldInitEvent; 13 | 14 | import com.github.hoqhuuep.islandcraft.api.ICWorld; 15 | import com.github.hoqhuuep.islandcraft.core.ICLogger; 16 | import com.github.hoqhuuep.islandcraft.core.IslandCache; 17 | import com.github.hoqhuuep.islandcraft.core.DefaultWorld; 18 | import com.github.hoqhuuep.islandcraft.core.ICClassLoader; 19 | import com.github.hoqhuuep.islandcraft.core.IslandDatabase; 20 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 21 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 22 | 23 | public class BiomeGeneratorListener implements Listener { 24 | private final Set worldsDone; 25 | private final IslandCraftPlugin islandCraft; 26 | private final IslandDatabase database; 27 | private final NmsWrapper nms; 28 | private final IslandCache cache; 29 | private final ICClassLoader classLoader; 30 | 31 | public BiomeGeneratorListener(final IslandCraftPlugin plugin, final IslandDatabase database, final NmsWrapper nms) { 32 | this.islandCraft = plugin; 33 | this.database = database; 34 | this.nms = nms; 35 | if (!islandCraft.getConfig().contains("worlds") || !islandCraft.getConfig().isConfigurationSection("worlds")) { 36 | ICLogger.logger.warning("No configuration section for 'worlds' found in config.yml"); 37 | throw new IllegalArgumentException("No configuration section for 'worlds' found in config.yml"); 38 | } 39 | worldsDone = new HashSet(); 40 | cache = new IslandCache(); 41 | classLoader = new ICClassLoader(); 42 | } 43 | 44 | @EventHandler 45 | public void onWorldInit(final WorldInitEvent event) { 46 | final World world = event.getWorld(); 47 | final String worldName = world.getName(); 48 | if (worldsDone.contains(worldName)) { 49 | return; 50 | } 51 | islandCraft.reloadConfig(); 52 | final ConfigurationSection worlds = islandCraft.getConfig().getConfigurationSection("worlds"); 53 | if (worlds == null) { 54 | return; 55 | } 56 | final ConfigurationSection config = worlds.getConfigurationSection(worldName); 57 | if (config == null) { 58 | return; 59 | } 60 | ICLogger.logger.info("Installing biome generator in WorldInitEvent for world with name: " + worldName); 61 | final ICWorld icWorld = new DefaultWorld(worldName, world.getSeed(), database, new BukkitWorldConfig(worldName, config), cache, classLoader); 62 | final BiomeGenerator biomeGenerator = new IslandCraftBiomeGenerator(icWorld); 63 | nms.installBiomeGenerator(world, biomeGenerator); 64 | worldsDone.add(worldName); 65 | islandCraft.getIslandCraft().addWorld(icWorld); 66 | } 67 | 68 | @EventHandler 69 | public void onChunkLoad(final ChunkLoadEvent event) { 70 | // First time server is run it will generate some chunks to find spawn 71 | // point this happens before WorldInitEvent. This event catches the 72 | // first one of those chunks, applies the hack, and regenerates the 73 | // chunk with the new WorldChunkManager. 74 | final World world = event.getWorld(); 75 | final String worldName = world.getName(); 76 | if (worldsDone.contains(worldName)) { 77 | return; 78 | } 79 | final ConfigurationSection worlds = islandCraft.getConfig().getConfigurationSection("worlds"); 80 | if (worlds == null) { 81 | return; 82 | } 83 | final ConfigurationSection config = worlds.getConfigurationSection(worldName); 84 | if (config == null) { 85 | return; 86 | } 87 | ICLogger.logger.info("Installing biome generator in ChunkLoadEvent for world with name: " + worldName); 88 | final ICWorld icWorld = new DefaultWorld(worldName, world.getSeed(), database, new BukkitWorldConfig(worldName, config), cache, classLoader); 89 | final BiomeGenerator biomeGenerator = new IslandCraftBiomeGenerator(icWorld); 90 | if (nms.installBiomeGenerator(world, biomeGenerator)) { 91 | // If this is the very first time, regenerate the chunk 92 | if (database.isEmpty(worldName)) { 93 | final Chunk chunk = event.getChunk(); 94 | ICLogger.logger.info(String.format("Regenerating spawn chunk at x: %d, z: %d", chunk.getX(), chunk.getZ())); 95 | world.regenerateChunk(chunk.getX(), chunk.getZ()); 96 | } 97 | } 98 | worldsDone.add(worldName); 99 | islandCraft.getIslandCraft().addWorld(icWorld); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /IslandCraft-Bukkit/src/main/java/com/github/hoqhuuep/islandcraft/bukkit/EbeanServerUtil.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.bukkit; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | import java.lang.reflect.Method; 5 | import java.util.List; 6 | 7 | import javax.persistence.PersistenceException; 8 | 9 | import org.bukkit.configuration.ConfigurationSection; 10 | import org.bukkit.plugin.java.JavaPlugin; 11 | 12 | import com.avaje.ebean.EbeanServer; 13 | import com.avaje.ebean.EbeanServerFactory; 14 | import com.avaje.ebean.config.DataSourceConfig; 15 | import com.avaje.ebean.config.ServerConfig; 16 | import com.avaje.ebean.config.dbplatform.SQLitePlatform; 17 | import com.avaje.ebeaninternal.api.SpiEbeanServer; 18 | import com.avaje.ebeaninternal.server.ddl.DdlGenerator; 19 | import com.avaje.ebeaninternal.server.lib.sql.TransactionIsolation; 20 | import com.github.hoqhuuep.islandcraft.core.ICLogger; 21 | 22 | public class EbeanServerUtil { 23 | public static EbeanServer build(final IslandCraftPlugin javaPlugin) { 24 | ICLogger.logger.info("Creating EbeanServer for plugin with name: " + javaPlugin.getDescription().getName()); 25 | final String name = javaPlugin.getDescription().getName(); 26 | final ConfigurationSection configurationSection = javaPlugin.getConfig().getConfigurationSection("database"); 27 | final String driver = configurationSection.getString("driver"); 28 | final String url = replaceDatabaseString(configurationSection.getString("url"), javaPlugin); 29 | final String username = configurationSection.getString("username"); 30 | final String password = configurationSection.getString("password"); 31 | final int isolationLevel = TransactionIsolation.getLevel(configurationSection.getString("isolation")); 32 | final List> classes = javaPlugin.getDatabaseClasses(); 33 | 34 | final ServerConfig serverConfig = new ServerConfig(); 35 | serverConfig.setDefaultServer(false); 36 | serverConfig.setRegister(false); 37 | serverConfig.setClasses(classes); 38 | serverConfig.setName(name); 39 | 40 | final DataSourceConfig dataSourceConfig = new DataSourceConfig(); 41 | dataSourceConfig.setDriver(driver); 42 | dataSourceConfig.setUrl(url); 43 | dataSourceConfig.setUsername(username); 44 | dataSourceConfig.setPassword(password); 45 | dataSourceConfig.setIsolationLevel(isolationLevel); 46 | 47 | if (driver.contains("sqlite")) { 48 | serverConfig.setDatabasePlatform(new SQLitePlatform()); 49 | serverConfig.getDatabasePlatform().getDbDdlSyntax().setIdentity(""); 50 | } 51 | serverConfig.setDataSourceConfig(dataSourceConfig); 52 | 53 | javaPlugin.getDataFolder().mkdirs(); 54 | final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 55 | Thread.currentThread().setContextClassLoader(getClassLoader(javaPlugin)); 56 | final EbeanServer ebeanServer = EbeanServerFactory.create(serverConfig); 57 | Thread.currentThread().setContextClassLoader(classLoader); 58 | 59 | // Hack to ensure database exists 60 | try { 61 | ebeanServer.find(classes.get(0)).findRowCount(); 62 | } catch (final PersistenceException e) { 63 | createDdl(ebeanServer); 64 | } 65 | 66 | return ebeanServer; 67 | } 68 | 69 | public static void createDdl(final EbeanServer ebeanServer) { 70 | final SpiEbeanServer spiEbeanServer = (SpiEbeanServer) ebeanServer; 71 | final DdlGenerator ddlGenerator = spiEbeanServer.getDdlGenerator(); 72 | ddlGenerator.runScript(false, ddlGenerator.generateCreateDdl()); 73 | } 74 | 75 | public static void dropDdl(final EbeanServer ebeanServer) { 76 | final SpiEbeanServer spiEbeanServer = (SpiEbeanServer) ebeanServer; 77 | final DdlGenerator ddlGenerator = spiEbeanServer.getDdlGenerator(); 78 | ddlGenerator.runScript(true, ddlGenerator.generateDropDdl()); 79 | } 80 | 81 | private static String replaceDatabaseString(String input, final JavaPlugin plugin) { 82 | input = input.replaceAll("\\{DIR\\}", plugin.getDataFolder().getPath().replaceAll("\\\\", "/") + "/"); 83 | input = input.replaceAll("\\{NAME\\}", plugin.getDescription().getName().replaceAll("[^\\w_-]", "")); 84 | return input; 85 | } 86 | 87 | private static ClassLoader getClassLoader(final JavaPlugin javaPlugin) { 88 | try { 89 | final Method method = JavaPlugin.class.getDeclaredMethod("getClassLoader"); 90 | method.setAccessible(true); 91 | return (ClassLoader) method.invoke(javaPlugin); 92 | } catch (SecurityException e) { 93 | throw new RuntimeException("Failed to retrieve the ClassLoader of the plugin using Reflection", e); 94 | } catch (NoSuchMethodException e) { 95 | throw new RuntimeException("Failed to retrieve the ClassLoader of the plugin using Reflection", e); 96 | } catch (IllegalAccessException e) { 97 | throw new RuntimeException("Failed to retrieve the ClassLoader of the plugin using Reflection", e); 98 | } catch (InvocationTargetException e) { 99 | throw new RuntimeException("Failed to retrieve the ClassLoader of the plugin using Reflection", e); 100 | } 101 | } 102 | 103 | private EbeanServerUtil() { 104 | // Utility class 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /IslandCraft-Bukkit/src/main/java/com/github/hoqhuuep/islandcraft/bukkit/EbeanServerIslandDatabase.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.bukkit; 2 | 3 | import java.io.Serializable; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Embeddable; 7 | import javax.persistence.EmbeddedId; 8 | import javax.persistence.Entity; 9 | import javax.persistence.Table; 10 | 11 | import com.avaje.ebean.EbeanServer; 12 | import com.github.hoqhuuep.islandcraft.core.ICLogger; 13 | import com.github.hoqhuuep.islandcraft.core.IslandDatabase; 14 | 15 | public class EbeanServerIslandDatabase implements IslandDatabase { 16 | private final EbeanServer ebeanServer; 17 | 18 | public EbeanServerIslandDatabase(final EbeanServer ebeanServer) { 19 | this.ebeanServer = ebeanServer; 20 | } 21 | 22 | @Override 23 | public void save(final String worldName, final int centerX, final int centerZ, final long islandSeed, final String generator) { 24 | ICLogger.logger.info(String.format("Saving IslandBean to database with worldName: %s, centerX: %d, centerZ: %d, islandSeed: %d, generator: %s", worldName, centerX, centerZ, islandSeed, generator)); 25 | final IslandBean bean = new IslandBean(new IslandPK(worldName, centerX, centerZ), islandSeed, generator); 26 | ebeanServer.save(bean); 27 | } 28 | 29 | @Override 30 | public Result load(final String worldName, final int centerX, final int centerZ) { 31 | ICLogger.logger.info(String.format("Loading IslandBean from database with worldName: %s, centerX: %d, centerZ: %d", worldName, centerX, centerZ)); 32 | final IslandPK pk = new IslandPK(worldName, centerX, centerZ); 33 | final IslandBean bean = ebeanServer.find(IslandBean.class, pk); 34 | if (bean == null) { 35 | ICLogger.logger.info("Result is null"); 36 | return null; 37 | } 38 | ICLogger.logger.info(String.format("Result has islandSeed: %d, generator: %s", bean.getIslandSeed(), bean.getGenerator())); 39 | return new Result(bean.getIslandSeed(), bean.getGenerator()); 40 | } 41 | 42 | @Override 43 | public boolean isEmpty(final String worldName) { 44 | ICLogger.logger.info("Checking if world contains any islands with worldName: " + worldName); 45 | boolean result = ebeanServer.find(IslandBean.class).where().ieq("world_name", worldName).findRowCount() == 0; 46 | ICLogger.logger.info("Result is: " + result); 47 | return result; 48 | } 49 | 50 | @Entity 51 | @Table(name = "islandcraft_core") 52 | public static class IslandBean { 53 | @EmbeddedId 54 | private IslandPK id; 55 | @Column(name = "island_seed") 56 | private long islandSeed; 57 | @Column(name = "generator") 58 | private String generator; 59 | 60 | public IslandBean() { 61 | // Default constructor 62 | } 63 | 64 | public IslandBean(final IslandPK id, final long islandSeed, final String generator) { 65 | this.id = id; 66 | this.islandSeed = islandSeed; 67 | this.generator = generator; 68 | } 69 | 70 | public IslandPK getId() { 71 | return id; 72 | } 73 | 74 | public long getIslandSeed() { 75 | return islandSeed; 76 | } 77 | 78 | public String getGenerator() { 79 | return generator; 80 | } 81 | 82 | public void setId(final IslandPK id) { 83 | this.id = id; 84 | } 85 | 86 | public void setIslandSeed(final long islandSeed) { 87 | this.islandSeed = islandSeed; 88 | } 89 | 90 | public void setGenerator(final String generator) { 91 | this.generator = generator; 92 | } 93 | } 94 | 95 | @Embeddable 96 | public static class IslandPK implements Serializable { 97 | private static final long serialVersionUID = -153559820620740595L; 98 | @Column(name = "world_name") 99 | private String worldName; 100 | @Column(name = "center_x") 101 | private int centerX; 102 | @Column(name = "center_z") 103 | private int centerZ; 104 | 105 | public IslandPK() { 106 | // Default constructor 107 | } 108 | 109 | public IslandPK(final String worldName, final int centerX, final int centerZ) { 110 | this.worldName = worldName; 111 | this.centerX = centerX; 112 | this.centerZ = centerZ; 113 | } 114 | 115 | public String getWorldName() { 116 | return worldName; 117 | } 118 | 119 | public int getCenterX() { 120 | return centerX; 121 | } 122 | 123 | public int getCenterZ() { 124 | return centerZ; 125 | } 126 | 127 | public void setWorldName(final String worldName) { 128 | this.worldName = worldName; 129 | } 130 | 131 | public void setCenterX(final int centerX) { 132 | this.centerX = centerX; 133 | } 134 | 135 | public void setCenterZ(final int centerZ) { 136 | this.centerZ = centerZ; 137 | } 138 | 139 | @Override 140 | public int hashCode() { 141 | final int prime = 31; 142 | int result = 1; 143 | result = prime * result + centerX; 144 | result = prime * result + centerZ; 145 | result = prime * result + ((worldName == null) ? 0 : worldName.hashCode()); 146 | return result; 147 | } 148 | 149 | @Override 150 | public boolean equals(Object obj) { 151 | if (this == obj) 152 | return true; 153 | if (obj == null) 154 | return false; 155 | if (getClass() != obj.getClass()) 156 | return false; 157 | IslandPK other = (IslandPK) obj; 158 | if (centerX != other.centerX) 159 | return false; 160 | if (centerZ != other.centerZ) 161 | return false; 162 | if (worldName == null) { 163 | if (other.worldName != null) 164 | return false; 165 | } else if (!worldName.equals(other.worldName)) 166 | return false; 167 | return true; 168 | } 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /IslandCraft-Sponge/src/main/java/com/github/hoqhuuep/islandcraft/IslandCraftBiomeGenerator.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft; 2 | 3 | import java.util.EnumMap; 4 | import java.util.Map; 5 | 6 | import org.spongepowered.api.world.biome.BiomeType; 7 | import org.spongepowered.api.world.biome.BiomeTypes; 8 | import org.spongepowered.api.world.extent.MutableBiomeArea; 9 | import org.spongepowered.api.world.gen.BiomeGenerator; 10 | 11 | import com.flowpowered.math.vector.Vector2i; 12 | import com.github.hoqhuuep.islandcraft.api.ICBiome; 13 | import com.github.hoqhuuep.islandcraft.api.ICWorld; 14 | import com.github.hoqhuuep.islandcraft.core.DefaultWorld; 15 | import com.github.hoqhuuep.islandcraft.core.ICClassLoader; 16 | import com.github.hoqhuuep.islandcraft.core.IslandCache; 17 | import com.github.hoqhuuep.islandcraft.core.IslandDatabase; 18 | 19 | import ninja.leaping.configurate.commented.CommentedConfigurationNode; 20 | 21 | public class IslandCraftBiomeGenerator implements BiomeGenerator { 22 | private final ICWorld icWorld; 23 | 24 | public IslandCraftBiomeGenerator(String worldName, long worldSeed, CommentedConfigurationNode config, IslandDatabase database) { 25 | icWorld = new DefaultWorld(worldName, worldSeed, database, new SpongeWorldConfig(config), new IslandCache(), new ICClassLoader()); 26 | } 27 | 28 | @Override 29 | public void generateBiomes(MutableBiomeArea buffer) { 30 | Vector2i min = buffer.getBiomeMin(); 31 | Vector2i max = buffer.getBiomeMax(); 32 | int xMin = min.getX(); 33 | int xMax = max.getX(); 34 | int zMin = min.getY(); 35 | int zMax = max.getY(); 36 | for (int z = zMin; z <= zMax; ++z) { 37 | for (int x = xMin; x <= xMax; ++x) { 38 | ICBiome icBiome = icWorld.getBiomeAt(x, z); 39 | buffer.setBiome(x, z, convertBiome(icBiome)); 40 | } 41 | } 42 | } 43 | 44 | private BiomeType convertBiome(ICBiome icBiome) { 45 | BiomeType spongeBiome = spongeBiomeFromICBiome.get(icBiome); 46 | if (spongeBiome == null) { 47 | return BiomeTypes.DEEP_OCEAN; 48 | } 49 | return spongeBiome; 50 | } 51 | 52 | private final Map spongeBiomeFromICBiome = new EnumMap(ICBiome.class); 53 | 54 | { 55 | spongeBiomeFromICBiome.put(ICBiome.BEACH, BiomeTypes.BEACH); 56 | spongeBiomeFromICBiome.put(ICBiome.BIRCH_FOREST, BiomeTypes.BIRCH_FOREST); 57 | spongeBiomeFromICBiome.put(ICBiome.BIRCH_FOREST_HILLS, BiomeTypes.BIRCH_FOREST_HILLS); 58 | spongeBiomeFromICBiome.put(ICBiome.BIRCH_FOREST_HILLS_M, BiomeTypes.BIRCH_FOREST_HILLS_MOUNTAINS); 59 | spongeBiomeFromICBiome.put(ICBiome.BIRCH_FOREST_M, BiomeTypes.BIRCH_FOREST_MOUNTAINS); 60 | spongeBiomeFromICBiome.put(ICBiome.COLD_BEACH, BiomeTypes.COLD_BEACH); 61 | spongeBiomeFromICBiome.put(ICBiome.COLD_TAIGA, BiomeTypes.COLD_TAIGA); 62 | spongeBiomeFromICBiome.put(ICBiome.COLD_TAIGA_HILLS, BiomeTypes.COLD_TAIGA_HILLS); 63 | spongeBiomeFromICBiome.put(ICBiome.COLD_TAIGA_M, BiomeTypes.COLD_TAIGA_MOUNTAINS); 64 | spongeBiomeFromICBiome.put(ICBiome.DEEP_OCEAN, BiomeTypes.DEEP_OCEAN); 65 | spongeBiomeFromICBiome.put(ICBiome.DESERT, BiomeTypes.DESERT); 66 | spongeBiomeFromICBiome.put(ICBiome.DESERT_HILLS, BiomeTypes.DESERT_HILLS); 67 | spongeBiomeFromICBiome.put(ICBiome.DESERT_M, BiomeTypes.DESERT_MOUNTAINS); 68 | spongeBiomeFromICBiome.put(ICBiome.END, BiomeTypes.SKY); 69 | spongeBiomeFromICBiome.put(ICBiome.EXTREME_HILLS, BiomeTypes.EXTREME_HILLS); 70 | spongeBiomeFromICBiome.put(ICBiome.EXTREME_HILLS_EDGE, BiomeTypes.EXTREME_HILLS_EDGE); 71 | spongeBiomeFromICBiome.put(ICBiome.EXTREME_HILLS_M, BiomeTypes.EXTREME_HILLS_MOUNTAINS); 72 | spongeBiomeFromICBiome.put(ICBiome.EXTREME_HILLS_PLUS, BiomeTypes.EXTREME_HILLS_PLUS); 73 | spongeBiomeFromICBiome.put(ICBiome.EXTREME_HILLS_PLUS_M, BiomeTypes.EXTREME_HILLS_PLUS_MOUNTAINS); 74 | spongeBiomeFromICBiome.put(ICBiome.FLOWER_FOREST, BiomeTypes.FLOWER_FOREST); 75 | spongeBiomeFromICBiome.put(ICBiome.FOREST, BiomeTypes.FOREST); 76 | spongeBiomeFromICBiome.put(ICBiome.FOREST_HILLS, BiomeTypes.FOREST_HILLS); 77 | spongeBiomeFromICBiome.put(ICBiome.FROZEN_OCEAN, BiomeTypes.FROZEN_OCEAN); 78 | spongeBiomeFromICBiome.put(ICBiome.FROZEN_RIVER, BiomeTypes.FROZEN_RIVER); 79 | spongeBiomeFromICBiome.put(ICBiome.ICE_MOUNTAINS, BiomeTypes.ICE_MOUNTAINS); 80 | spongeBiomeFromICBiome.put(ICBiome.ICE_PLAINS, BiomeTypes.ICE_PLAINS); 81 | spongeBiomeFromICBiome.put(ICBiome.ICE_PLAINS_SPIKES, BiomeTypes.ICE_PLAINS_SPIKES); 82 | spongeBiomeFromICBiome.put(ICBiome.JUNGLE, BiomeTypes.JUNGLE); 83 | spongeBiomeFromICBiome.put(ICBiome.JUNGLE_EDGE, BiomeTypes.JUNGLE_EDGE); 84 | spongeBiomeFromICBiome.put(ICBiome.JUNGLE_HILLS, BiomeTypes.JUNGLE_HILLS); 85 | spongeBiomeFromICBiome.put(ICBiome.JUNGLE_M, BiomeTypes.JUNGLE_MOUNTAINS); 86 | spongeBiomeFromICBiome.put(ICBiome.JUNGLE_EDGE_M, BiomeTypes.JUNGLE_EDGE_MOUNTAINS); 87 | spongeBiomeFromICBiome.put(ICBiome.MEGA_SPRUCE_TAIGA, BiomeTypes.MEGA_SPRUCE_TAIGA); 88 | spongeBiomeFromICBiome.put(ICBiome.MEGA_SPRUCE_TAIGA_HILLS, BiomeTypes.MEGA_SPRUCE_TAIGA_HILLS); 89 | spongeBiomeFromICBiome.put(ICBiome.MEGA_TAIGA, BiomeTypes.MEGA_TAIGA); 90 | spongeBiomeFromICBiome.put(ICBiome.MEGA_TAIGA_HILLS, BiomeTypes.MEGA_TAIGA_HILLS); 91 | spongeBiomeFromICBiome.put(ICBiome.MESA, BiomeTypes.MESA); 92 | spongeBiomeFromICBiome.put(ICBiome.MESA_BRYCE, BiomeTypes.MESA_BRYCE); 93 | spongeBiomeFromICBiome.put(ICBiome.MESA_PLATEAU, BiomeTypes.MESA_PLATEAU); 94 | spongeBiomeFromICBiome.put(ICBiome.MESA_PLATEAU_F, BiomeTypes.MESA_PLATEAU_FOREST); 95 | spongeBiomeFromICBiome.put(ICBiome.MESA_PLATEAU_F_M, BiomeTypes.MESA_PLATEAU_FOREST_MOUNTAINS); 96 | spongeBiomeFromICBiome.put(ICBiome.MESA_PLATEAU_M, BiomeTypes.MESA_PLATEAU_MOUNTAINS); 97 | spongeBiomeFromICBiome.put(ICBiome.MUSHROOM_ISLAND, BiomeTypes.MUSHROOM_ISLAND); 98 | spongeBiomeFromICBiome.put(ICBiome.MUSHROOM_ISLAND_SHORE, BiomeTypes.MUSHROOM_ISLAND_SHORE); 99 | spongeBiomeFromICBiome.put(ICBiome.NETHER, BiomeTypes.HELL); 100 | spongeBiomeFromICBiome.put(ICBiome.OCEAN, BiomeTypes.OCEAN); 101 | spongeBiomeFromICBiome.put(ICBiome.PLAINS, BiomeTypes.PLAINS); 102 | spongeBiomeFromICBiome.put(ICBiome.RIVER, BiomeTypes.RIVER); 103 | spongeBiomeFromICBiome.put(ICBiome.ROOFED_FOREST, BiomeTypes.ROOFED_FOREST); 104 | spongeBiomeFromICBiome.put(ICBiome.ROOFED_FOREST_M, BiomeTypes.ROOFED_FOREST_MOUNTAINS); 105 | spongeBiomeFromICBiome.put(ICBiome.SAVANNA, BiomeTypes.SAVANNA); 106 | spongeBiomeFromICBiome.put(ICBiome.SAVANNA_M, BiomeTypes.SAVANNA_MOUNTAINS); 107 | spongeBiomeFromICBiome.put(ICBiome.SAVANNA_PLATEAU, BiomeTypes.SAVANNA_PLATEAU); 108 | spongeBiomeFromICBiome.put(ICBiome.SAVANNA_PLATEAU_M, BiomeTypes.SAVANNA_PLATEAU_MOUNTAINS); 109 | spongeBiomeFromICBiome.put(ICBiome.STONE_BEACH, BiomeTypes.STONE_BEACH); 110 | spongeBiomeFromICBiome.put(ICBiome.SUNFLOWER_PLAINS, BiomeTypes.SUNFLOWER_PLAINS); 111 | spongeBiomeFromICBiome.put(ICBiome.SWAMPLAND, BiomeTypes.SWAMPLAND); 112 | spongeBiomeFromICBiome.put(ICBiome.SWAMPLAND_M, BiomeTypes.SWAMPLAND_MOUNTAINS); 113 | spongeBiomeFromICBiome.put(ICBiome.TAIGA, BiomeTypes.TAIGA); 114 | spongeBiomeFromICBiome.put(ICBiome.TAIGA_HILLS, BiomeTypes.TAIGA_HILLS); 115 | spongeBiomeFromICBiome.put(ICBiome.TAIGA_M, BiomeTypes.TAIGA_MOUNTAINS); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/IslandGeneratorAlpha.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core; 2 | 3 | import java.awt.AlphaComposite; 4 | import java.awt.Color; 5 | import java.awt.Graphics2D; 6 | import java.awt.image.BufferedImage; 7 | import java.util.ArrayList; 8 | import java.util.LinkedList; 9 | import java.util.List; 10 | import java.util.Queue; 11 | import java.util.Random; 12 | 13 | import com.github.hoqhuuep.islandcraft.api.ICBiome; 14 | import com.github.hoqhuuep.islandcraft.api.IslandGenerator; 15 | import com.github.hoqhuuep.islandcraft.core.mosaic.Poisson; 16 | import com.github.hoqhuuep.islandcraft.core.mosaic.Site; 17 | import com.github.hoqhuuep.islandcraft.core.noise.Noise; 18 | import com.github.hoqhuuep.islandcraft.core.noise.OctaveNoise; 19 | import com.github.hoqhuuep.islandcraft.util.StringUtils; 20 | 21 | public class IslandGeneratorAlpha implements IslandGenerator { 22 | private static final double MIN_DISTANCE = 8; 23 | private static final double NOISE = 2.7; 24 | private static final double CIRCLE = 2; 25 | private static final double SQUARE = 0; 26 | private static final double THRESHOLD = 2; 27 | private final Color ocean; 28 | private final Color normal; 29 | private final Color mountains; 30 | private final Color hills; 31 | private final Color hillsMountains; 32 | private final Color forest; 33 | private final Color forestMountains; 34 | private final Color outerCoast; 35 | private final Color innerCoast; 36 | 37 | // private final Color river; // unused for now 38 | 39 | public IslandGeneratorAlpha(final String[] args) { 40 | ICLogger.logger.info("Creating IslandGeneratorAlpha with args: " + StringUtils.join(args, " ")); 41 | if (args.length != 9) { 42 | ICLogger.logger.error("IslandGeneratorAlpha requrires 9 parameters, " + args.length + " given"); 43 | throw new IllegalArgumentException("IslandGeneratorAlpha requrires 9 parameters"); 44 | } 45 | ocean = new Color(ICBiome.values().length, true); 46 | normal = biomeColor(args[0], ocean); 47 | mountains = biomeColor(args[1], normal); 48 | hills = biomeColor(args[2], normal); 49 | hillsMountains = biomeColor(args[3], hills); 50 | forest = biomeColor(args[4], normal); 51 | forestMountains = biomeColor(args[5], forest); 52 | outerCoast = biomeColor(args[6], normal); 53 | innerCoast = biomeColor(args[7], normal); 54 | // river = biomeColor(args[8], normal); // unused for now 55 | } 56 | 57 | @Override 58 | public ICBiome[] generate(final int xSize, final int zSize, final long islandSeed) { 59 | ICLogger.logger.info(String.format( 60 | "Generating island from IslandGeneratorAlpha with xSize: %d, zSize: %d, islandSeed: %d, biome: %s", 61 | xSize, zSize, islandSeed, ICBiome.values()[normal.getRGB()])); 62 | final Poisson poisson = new Poisson(xSize, zSize, MIN_DISTANCE); 63 | final List sites = poisson.generate(new Random(islandSeed)); 64 | final Noise shapeNoise = new OctaveNoise(islandSeed); 65 | final Noise hillsNoise = new OctaveNoise(islandSeed + 1); 66 | final Noise forestNoise = new OctaveNoise(islandSeed + 2); 67 | final Noise mountainsNoise = new OctaveNoise(islandSeed + 3); 68 | // Find borders 69 | final Queue oceanSites = new LinkedList(); 70 | for (final Site site : sites) { 71 | if (site.polygon == null) { 72 | site.isOcean = true; 73 | oceanSites.add(site); 74 | } 75 | } 76 | final List suspectCoast = new ArrayList(); 77 | final List coast = new ArrayList(); 78 | // Find oceans and coasts 79 | while (!oceanSites.isEmpty()) { 80 | final Site site = oceanSites.remove(); 81 | for (final Site neighbor : site.neighbors) { 82 | if (site.polygon == null) { 83 | if (!neighbor.isOcean) { 84 | neighbor.isOcean = true; 85 | oceanSites.add(neighbor); 86 | } 87 | } else { 88 | final double dx = (double) (neighbor.x - (xSize / 2)) / (double) (xSize / 2); 89 | final double dz = (double) (neighbor.z - (zSize / 2)) / (double) (zSize / 2); 90 | if (NOISE * noise(dx, dz, shapeNoise) + CIRCLE * circle(dx, dz) 91 | + SQUARE * square(dx, dz) > THRESHOLD) { 92 | if (!neighbor.isOcean) { 93 | neighbor.isOcean = true; 94 | oceanSites.add(neighbor); 95 | } 96 | } else { 97 | neighbor.isInnerCoast = true; 98 | suspectCoast.add(neighbor); 99 | } 100 | } 101 | } 102 | } 103 | // Create coast 104 | SITE: for (final Site site : suspectCoast) { 105 | for (final Site neighbor : site.neighbors) { 106 | if (!neighbor.isOcean && !neighbor.isInnerCoast) { 107 | coast.add(site); 108 | continue SITE; 109 | } 110 | } 111 | site.isInnerCoast = false; 112 | site.isOcean = true; 113 | } 114 | // Create shallow ocean 115 | for (final Site site : coast) { 116 | for (final Site neighbor : site.neighbors) { 117 | if (neighbor.isOcean) { 118 | neighbor.isOcean = false; 119 | neighbor.isOuterCoast = true; 120 | } 121 | } 122 | } 123 | // Create blank image 124 | final BufferedImage image = new BufferedImage(xSize, zSize, BufferedImage.TYPE_INT_ARGB); 125 | final Graphics2D graphics = image.createGraphics(); 126 | graphics.setComposite(AlphaComposite.Src); 127 | graphics.setBackground(ocean); 128 | graphics.clearRect(0, 0, xSize, zSize); 129 | // Render island 130 | for (final Site site : sites) { 131 | if (site.isOcean) { 132 | continue; 133 | } else if (site.isOuterCoast) { 134 | graphics.setColor(outerCoast); 135 | } else if (site.isInnerCoast) { 136 | graphics.setColor(innerCoast); 137 | } else if (noise(site, 0.375, 160.0, mountainsNoise)) { 138 | if (noise(site, 0.375, 80.0, hillsNoise)) { 139 | graphics.setColor(hillsMountains); 140 | } else if (noise(site, 0.375, 160.0, forestNoise)) { 141 | graphics.setColor(forestMountains); 142 | } else { 143 | graphics.setColor(mountains); 144 | } 145 | } else { 146 | if (noise(site, 0.375, 80.0, hillsNoise)) { 147 | graphics.setColor(hills); 148 | } else if (noise(site, 0.375, 160.0, forestNoise)) { 149 | graphics.setColor(forest); 150 | } else { 151 | graphics.setColor(normal); 152 | } 153 | } 154 | graphics.fillPolygon(site.polygon); 155 | graphics.drawPolygon(site.polygon); 156 | } 157 | // Save result 158 | graphics.dispose(); 159 | final ICBiome[] result = new ICBiome[xSize * zSize]; 160 | final ICBiome[] values = ICBiome.values(); 161 | final int maxOrdinal = values.length; 162 | for (int i = 0; i < result.length; ++i) { 163 | final int x = i % xSize; 164 | final int z = i / xSize; 165 | final int ordinal = image.getRGB(x, z); 166 | if (ordinal < maxOrdinal) { 167 | result[i] = values[ordinal]; 168 | } 169 | } 170 | return result; 171 | } 172 | 173 | private static Color biomeColor(final String name, final Color backup) { 174 | if (name.equals("~")) { 175 | return backup; 176 | } 177 | return new Color(ICBiome.valueOf(name).ordinal(), true); 178 | } 179 | 180 | private static boolean noise(final Site site, final double threshold, final double period, final Noise noise) { 181 | return noise.noise(site.x / period, site.z / period) < threshold; 182 | } 183 | 184 | private static double noise(final double dx, final double dz, final Noise noise) { 185 | return noise.noise(dx, dz); 186 | } 187 | 188 | private static double circle(final double dx, final double dz) { 189 | return (dx * dx + dz * dz) / 2; 190 | } 191 | 192 | private static double square(final double dx, final double dz) { 193 | return Math.max(Math.abs(dx), Math.abs(dz)); 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/SquareIslandDistribution.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | import com.github.hoqhuuep.islandcraft.api.ICLocation; 7 | import com.github.hoqhuuep.islandcraft.api.ICRegion; 8 | import com.github.hoqhuuep.islandcraft.api.IslandDistribution; 9 | import com.github.hoqhuuep.islandcraft.util.StringUtils; 10 | 11 | public class SquareIslandDistribution implements IslandDistribution { 12 | private final int islandSize; 13 | private final int oceanSize; 14 | private final int islandSeparation; 15 | private final int innerRadius; 16 | private final int outerRadius; 17 | 18 | public SquareIslandDistribution(final String[] args) { 19 | ICLogger.logger.info("Creating SquareIslandDistribution with args: " + StringUtils.join(args, " ")); 20 | if (args.length != 2) { 21 | ICLogger.logger.error("SquareIslandDistribution requrires 2 parameters, " + args.length + " given"); 22 | throw new IllegalArgumentException("SquareIslandDistribution requrires 2 parameters"); 23 | } 24 | islandSize = Integer.parseInt(args[0]); 25 | oceanSize = Integer.parseInt(args[1]); 26 | // Validate configuration values 27 | if (islandSize <= 0 || islandSize % 32 != 0) { 28 | ICLogger.logger.error("SquareIslandDistribution.island-size must be a positive multiple of 32"); 29 | throw new IllegalArgumentException("SquareIslandDistribution.island-size must be a positive multiple of 32"); 30 | } 31 | if (oceanSize <= 0 || oceanSize % 32 != 0) { 32 | ICLogger.logger.error("SquareIslandDistribution.ocean-size must be a positive multiple of 32"); 33 | throw new IllegalArgumentException("SquareIslandDistribution.ocean-size must be a positive multiple of 32"); 34 | } 35 | islandSeparation = islandSize + oceanSize; 36 | innerRadius = islandSize / 2; 37 | outerRadius = innerRadius + oceanSize; 38 | } 39 | 40 | @Override 41 | public ICLocation getCenterAt(int x, int z, final long worldSeed) { 42 | // xPrime, zPrime = shift the coordinate system so that 0, 0 is top-left 43 | // of spawn island 44 | // xRelative, zRelative = coordinates relative to top-left of nearest 45 | // island 46 | // row, column = nearest island 47 | final int zPrime = z + islandSize / 2; 48 | final int zRelative = ifloormod(zPrime, islandSeparation); 49 | if (zRelative >= islandSize) { 50 | return null; 51 | } 52 | final int row = ifloordiv(zPrime, islandSeparation); 53 | final int xPrime = x + islandSize / 2; 54 | final int xRelative = ifloormod(xPrime, islandSeparation); 55 | if (xRelative >= islandSize) { 56 | return null; 57 | } 58 | final int column = ifloordiv(xPrime, islandSeparation); 59 | return getCenter(row, column); 60 | } 61 | 62 | @Override 63 | public Set getCentersAt(int x, int z, final long worldSeed) { 64 | // Numbers represent how many island regions a location overlaps. 65 | // Arrows point towards the centers of the overlapped regions. 66 | // @-------+-------------------------------+ 67 | // |..\./..|...............^...............| 68 | // |...4...|...............2...............| 69 | // |../.\..|...............v...............| 70 | // +-------+-------------------------------+ 71 | // |.......|...............................| 72 | // |.......|...............................| 73 | // |.......|...............................| 74 | // |.......|...............................| 75 | // |.......|...............................| 76 | // |.......|...............................| 77 | // |..<2>..|...............#...............| 78 | // |.......|...............................| 79 | // |.......|...............................| 80 | // |.......|...............................| 81 | // |.......|...............................| 82 | // |.......|...............................| 83 | // |.......|...............................| 84 | // +-------+-------------------------------+ 85 | // # relative to @ 86 | final int xPrime = x + outerRadius; 87 | final int zPrime = z + outerRadius; 88 | // # relative to world origin 89 | final int absoluteHashX = ifloordiv(xPrime, islandSeparation) * islandSeparation; 90 | final int absoluteHashZ = ifloordiv(zPrime, islandSeparation) * islandSeparation; 91 | // Point to test relative to @ 92 | final int relativeX = xPrime - absoluteHashX; 93 | final int relativeZ = zPrime - absoluteHashZ; 94 | final Set result = new HashSet(3); 95 | 96 | if (relativeZ < oceanSize) { 97 | final int centerZ = absoluteHashZ - islandSeparation; 98 | if (relativeX < oceanSize) { 99 | final int centerX = absoluteHashX - islandSeparation; 100 | result.add(getCenter(centerX, centerZ)); 101 | result.add(getCenter(centerX, absoluteHashZ)); 102 | } 103 | result.add(getCenter(absoluteHashX, centerZ)); 104 | } else if (relativeX < oceanSize) { 105 | final int centerX = absoluteHashX - islandSeparation; 106 | result.add(getCenter(centerX, absoluteHashZ)); 107 | } 108 | // Center 109 | result.add(getCenter(absoluteHashX, absoluteHashZ)); 110 | return result; 111 | } 112 | 113 | @Override 114 | public ICRegion getInnerRegion(final ICLocation center, final long worldSeed) { 115 | final int centerX = center.getX(); 116 | final int centerZ = center.getZ(); 117 | if (!isCenter(centerX, centerZ)) { 118 | return null; 119 | } 120 | return new ICRegion(new ICLocation(centerX - innerRadius, centerZ - innerRadius), new ICLocation(centerX + innerRadius, centerZ + innerRadius)); 121 | } 122 | 123 | @Override 124 | public ICRegion getOuterRegion(final ICLocation center, final long worldSeed) { 125 | final int centerX = center.getX(); 126 | final int centerZ = center.getZ(); 127 | if (!isCenter(centerX, centerZ)) { 128 | return null; 129 | } 130 | return new ICRegion(new ICLocation(centerX - outerRadius, centerZ - outerRadius), new ICLocation(centerX + outerRadius, centerZ + outerRadius)); 131 | } 132 | 133 | private ICLocation getCenter(final int row, final int column) { 134 | final int centerZ = row * islandSeparation; 135 | final int centerX = column * islandSeparation; 136 | return new ICLocation(centerX, centerZ); 137 | } 138 | 139 | private boolean isCenter(final int centerX, final int centerZ) { 140 | return ifloormod(centerZ, islandSeparation) == 0 && ifloormod(centerX, islandSeparation) == 0; 141 | } 142 | 143 | private static int ifloordiv(int n, int d) { 144 | // Credit to Mark Dickinson 145 | // http://stackoverflow.com/a/10466453 146 | if (d >= 0) 147 | return n >= 0 ? n / d : ~(~n / d); 148 | else 149 | return n <= 0 ? n / d : (n - 1) / d - 1; 150 | } 151 | 152 | private static int ifloormod(int n, int d) { 153 | // Credit to Mark Dickinson 154 | // http://stackoverflow.com/a/10466453 155 | if (d >= 0) 156 | return n >= 0 ? n % d : d + ~(~n % d); 157 | else 158 | return n <= 0 ? n % d : d + 1 + (n - 1) % d; 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/DefaultWorld.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.HashSet; 6 | import java.util.List; 7 | import java.util.Random; 8 | import java.util.Set; 9 | 10 | import com.github.hoqhuuep.islandcraft.api.BiomeDistribution; 11 | import com.github.hoqhuuep.islandcraft.api.ICBiome; 12 | import com.github.hoqhuuep.islandcraft.api.ICIsland; 13 | import com.github.hoqhuuep.islandcraft.api.ICLocation; 14 | import com.github.hoqhuuep.islandcraft.api.ICRegion; 15 | import com.github.hoqhuuep.islandcraft.api.ICWorld; 16 | import com.github.hoqhuuep.islandcraft.api.IslandDistribution; 17 | import com.github.hoqhuuep.islandcraft.util.Cache; 18 | import com.github.hoqhuuep.islandcraft.util.CacheLoader; 19 | import com.github.hoqhuuep.islandcraft.util.ExpiringLoadingCache; 20 | import com.github.hoqhuuep.islandcraft.util.StringUtils; 21 | 22 | public class DefaultWorld implements ICWorld { 23 | private final String worldName; 24 | private final long worldSeed; 25 | private final IslandDatabase database; 26 | private final BiomeDistribution ocean; 27 | private final IslandDistribution islandDistribution; 28 | private final List islandGenerators; 29 | private final IslandCache cache; 30 | private final ICClassLoader classLoader; 31 | private final Cache databaseCache; 32 | 33 | public DefaultWorld(final String name, final long seed, final IslandDatabase database, final ICWorldConfig config, final IslandCache cache, final ICClassLoader classLoader) { 34 | this.worldName = name; 35 | this.worldSeed = seed; 36 | this.database = database; 37 | this.cache = cache; 38 | this.classLoader = classLoader; 39 | 40 | ocean = classLoader.getBiomeDistribution(config.getOcean()); 41 | islandDistribution = classLoader.getIslandDistribution(config.getIslandDistribution()); 42 | islandGenerators = new ArrayList(Arrays.asList(config.getIslandGenerstors())); 43 | // Load islandGenerators just to make sure there are no errors 44 | for (final String islandGenerator : islandGenerators) { 45 | classLoader.getIslandGenerator(islandGenerator); 46 | } 47 | 48 | databaseCache = new ExpiringLoadingCache(30, new DatabaseCacheLoader()); 49 | } 50 | 51 | @Override 52 | public long getSeed() { 53 | return worldSeed; 54 | } 55 | 56 | @Override 57 | public String getName() { 58 | return worldName; 59 | } 60 | 61 | @Override 62 | public ICBiome getBiomeAt(final ICLocation location) { 63 | return getBiomeAt(location.getX(), location.getZ()); 64 | } 65 | 66 | @Override 67 | public ICBiome getBiomeAt(final int x, final int z) { 68 | final ICIsland island = getIslandAt(x, z); 69 | if (island == null) { 70 | return ocean.biomeAt(x, z, worldSeed); 71 | } 72 | final ICLocation origin = island.getInnerRegion().getMin(); 73 | final ICBiome biome = island.getBiomeAt(x - origin.getX(), z - origin.getZ()); 74 | if (biome == null) { 75 | return ocean.biomeAt(x, z, worldSeed); 76 | } 77 | return biome; 78 | } 79 | 80 | @Override 81 | public ICBiome[] getBiomeChunk(ICLocation location) { 82 | return getBiomeChunk(location.getX(), location.getZ()); 83 | } 84 | 85 | @Override 86 | public ICBiome[] getBiomeChunk(int x, int z) { 87 | final ICIsland island = getIslandAt(x, z); 88 | if (island == null) { 89 | final ICBiome[] chunk = new ICBiome[256]; 90 | for (int i = 0; i < 256; ++i) { 91 | chunk[i] = ocean.biomeAt(x + i % 16, z + i / 16, worldSeed); 92 | } 93 | return chunk; 94 | } 95 | final ICLocation origin = island.getInnerRegion().getMin(); 96 | final ICBiome[] biomes = island.getBiomeChunk(x - origin.getX(), z - origin.getZ()); 97 | if (biomes == null) { 98 | final ICBiome[] chunk = new ICBiome[256]; 99 | for (int i = 0; i < 256; ++i) { 100 | chunk[i] = ocean.biomeAt(x + i % 16, z + i / 16, worldSeed); 101 | } 102 | return chunk; 103 | } 104 | for (int i = 0; i < 256; ++i) { 105 | if (biomes[i] == null) { 106 | biomes[i] = ocean.biomeAt(x + i % 16, z + i / 16, worldSeed); 107 | } 108 | } 109 | return biomes; 110 | } 111 | 112 | @Override 113 | public ICIsland getIslandAt(final ICLocation location) { 114 | return getIslandAt(location.getX(), location.getZ()); 115 | } 116 | 117 | @Override 118 | public ICIsland getIslandAt(final int x, final int z) { 119 | final ICLocation center = islandDistribution.getCenterAt(x, z, worldSeed); 120 | if (center == null) { 121 | return null; 122 | } 123 | return databaseCache.get(center); 124 | } 125 | 126 | @Override 127 | public Set getIslandsAt(final ICLocation location) { 128 | return getIslandsAt(location.getX(), location.getZ()); 129 | } 130 | 131 | @Override 132 | public Set getIslandsAt(final int x, final int z) { 133 | final Set centers = islandDistribution.getCentersAt(x, z, worldSeed); 134 | final Set islands = new HashSet(centers.size()); 135 | for (final ICLocation center : centers) { 136 | islands.add(databaseCache.get(center)); 137 | } 138 | return islands; 139 | } 140 | 141 | private class DatabaseCacheLoader implements CacheLoader { 142 | @Override 143 | public ICIsland load(final ICLocation center) { 144 | final ICRegion innerRegion = islandDistribution.getInnerRegion(center, worldSeed); 145 | final ICRegion outerRegion = islandDistribution.getOuterRegion(center, worldSeed); 146 | final IslandDatabase.Result fromDatabase = database.load(worldName, center.getX(), center.getZ()); 147 | if (fromDatabase == null) { 148 | final long islandSeed = pickIslandSeed(center.getX(), center.getZ()); 149 | final String generator = pickIslandGenerator(islandSeed); 150 | database.save(worldName, center.getX(), center.getZ(), islandSeed, generator); 151 | return new DefaultIsland(innerRegion, outerRegion, islandSeed, classLoader.getIslandGenerator(generator), cache); 152 | } 153 | return new DefaultIsland(innerRegion, outerRegion, fromDatabase.getIslandSeed(), classLoader.getIslandGenerator(fromDatabase.getGenerator()), cache); 154 | } 155 | 156 | private long pickIslandSeed(final int centerX, final int centerZ) { 157 | return new Random(worldSeed ^ ((long) centerX << 24 | centerZ & 0x00FFFFFFL)).nextLong(); 158 | } 159 | 160 | private String pickIslandGenerator(final long islandSeed) { 161 | return islandGenerators.get(new Random(islandSeed).nextInt(islandGenerators.size())); 162 | } 163 | } 164 | 165 | @Override 166 | public int hashCode() { 167 | return worldName.hashCode(); 168 | } 169 | 170 | @Override 171 | public boolean equals(final Object obj) { 172 | if (this == obj) 173 | return true; 174 | if (obj == null) 175 | return false; 176 | if (getClass() != obj.getClass()) 177 | return false; 178 | final DefaultWorld other = (DefaultWorld) obj; 179 | return StringUtils.equals(worldName, other.worldName); 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/mosaic/Poisson.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core.mosaic; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.Iterator; 6 | import java.util.List; 7 | import java.util.Random; 8 | 9 | public final class Poisson { 10 | private final double xSize; 11 | private final double zSize; 12 | private final double radius; 13 | private final double diameter; 14 | private final double maxQuadrance; 15 | 16 | public Poisson(final double xSize, final double zSize, final double radius) { 17 | this.xSize = xSize; 18 | this.zSize = zSize; 19 | this.radius = radius; 20 | diameter = 2.0 * radius; 21 | maxQuadrance = diameter * diameter; 22 | } 23 | 24 | public List generate(final Random random) { 25 | final List candidates = new ArrayList(); 26 | final List sites = new ArrayList(); 27 | final Grid grid = new Grid((int) Math.ceil(xSize / diameter), (int) Math.ceil(zSize / diameter)); 28 | final Site firstSite = randomPoint(xSize, zSize, random); 29 | candidates.add(firstSite); 30 | sites.add(firstSite); 31 | gridAdd(grid, firstSite); 32 | while (!candidates.isEmpty()) { 33 | final Site candidate = candidates.remove(candidates.size() - 1); 34 | final RangeList rangeList = new RangeList(); 35 | for (final Site neighbor : gridNeighbors(grid, candidate)) { 36 | if (neighbor != candidate) { 37 | subtractPoint(rangeList, candidate, neighbor); 38 | } 39 | } 40 | subtractEdges(rangeList, candidate); 41 | while (!rangeList.isEmpty()) { 42 | final double angle = rangeList.random(random); 43 | final Site newSite = makePoint(candidate, angle); 44 | sites.add(newSite); 45 | candidates.add(newSite); 46 | newSite.parent = candidate; 47 | gridAdd(grid, newSite); 48 | subtractPoint(rangeList, candidate, newSite); 49 | } 50 | } 51 | firstSite.parent = sites.get(1); 52 | // Find Voronoi neighbors 53 | for (final Site s : sites) { 54 | if (s.polygon == null) { 55 | continue; 56 | } 57 | Collections.sort(s.suspectNeighbors, new AngleComparator(s.parent, s)); 58 | final Iterator iterator = s.suspectNeighbors.iterator(); 59 | Site pa = iterator.next(); 60 | A: while (iterator.hasNext()) { 61 | final Site pb = iterator.next(); 62 | final Site cc = circumcenter(s, pa, pb); 63 | final double cq = absq(AngleComparator.sub(s, cc)); 64 | for (final Site pc : s.suspectNeighbors) { 65 | if (pc != pa && pc != pb && absq(AngleComparator.sub(pc, cc)) < cq) { 66 | continue A; 67 | } 68 | } 69 | s.neighbors.add(pb); 70 | if (pb.polygon == null) { 71 | pb.neighbors.add(s); 72 | } 73 | s.polygon.addPoint((int) cc.x, (int) cc.z); 74 | pa = pb; 75 | } 76 | s.neighbors.add(s.parent); 77 | if (s.parent.polygon == null) { 78 | s.parent.neighbors.add(s); 79 | } 80 | final Site cc = circumcenter(s, pa, s.parent); 81 | s.polygon.addPoint((int) cc.x, (int) cc.z); 82 | } 83 | return sites; 84 | } 85 | 86 | private Site circumcenter(final Site p1, final Site p2, final Site p3) { 87 | final double q1 = absq(p1); 88 | final double q2 = absq(p2); 89 | final double q3 = absq(p3); 90 | final Site s12 = AngleComparator.sub(p1, p2); 91 | final Site s23 = AngleComparator.sub(p2, p3); 92 | final Site s31 = AngleComparator.sub(p3, p1); 93 | final double d = 0.5 / (p1.x * s23.z + p2.x * s31.z + p3.x * s12.z); 94 | final double cx = (q1 * s23.z + q2 * s31.z + q3 * s12.z) * d; 95 | final double cz = -(q1 * s23.x + q2 * s31.x + q3 * s12.x) * d; 96 | return new Site(cx, cz); 97 | } 98 | 99 | private double absq(final Site p) { 100 | return p.x * p.x + p.z * p.z; 101 | } 102 | 103 | private List gridNeighbors(final Grid grid, final Site candidate) { 104 | int xMin = (int) Math.floor(candidate.x / diameter) - 1; 105 | int zMin = (int) Math.floor(candidate.z / diameter) - 1; 106 | int xMax = (int) Math.ceil(candidate.x / diameter) + 1; 107 | int zMax = (int) Math.ceil(candidate.z / diameter) + 1; 108 | if (xMin < 0) { 109 | xMin = 0; 110 | } 111 | if (zMin < 0) { 112 | zMin = 0; 113 | } 114 | if (xMax > xSize / diameter) { 115 | xMax = (int) Math.floor(xSize / diameter); 116 | } 117 | if (zMax > zSize / diameter) { 118 | zMax = (int) Math.floor(zSize / diameter); 119 | } 120 | return grid.getRegion(xMin, zMin, xMax, zMax); 121 | } 122 | 123 | private void gridAdd(final Grid grid, final Site site) { 124 | int xRow = (int) Math.floor(site.x / diameter); 125 | int zRow = (int) Math.floor(site.z / diameter); 126 | grid.add(xRow, zRow, site); 127 | } 128 | 129 | private Site makePoint(final Site site, final double angle) { 130 | final double x = site.x + Math.cos(angle) * radius; 131 | final double z = site.z + Math.sin(angle) * radius; 132 | return new Site(x, z); 133 | } 134 | 135 | private void subtractPoint(final RangeList rangeList, final Site candidate, final Site point) { 136 | final double dx = point.x - candidate.x; 137 | final double dz = point.z - candidate.z; 138 | final double quadrance = dx * dx + dz * dz; 139 | if (quadrance < maxQuadrance) { 140 | final double distance = Math.sqrt(quadrance); 141 | final double angle = Math.atan2(dz, dx); 142 | final double theta = Math.acos(distance / diameter); 143 | rangeList.subtract(angle - theta, angle + theta); 144 | if (!candidate.suspectNeighbors.contains(point)) { 145 | candidate.suspectNeighbors.add(point); 146 | } 147 | if (!point.suspectNeighbors.contains(candidate)) { 148 | point.suspectNeighbors.add(candidate); 149 | } 150 | } 151 | } 152 | 153 | private void subtractEdges(final RangeList rangeList, final Site site) { 154 | final double x = site.x; 155 | final double z = site.z; 156 | if (x < radius) { 157 | final double theta = Math.acos(x / radius); 158 | rangeList.subtract(Math.PI - theta, Math.PI + theta); 159 | site.polygon = null; 160 | } 161 | if (z < radius) { 162 | final double theta = Math.acos(z / radius); 163 | rangeList.subtract((Math.PI * 3) / 2 - theta, (Math.PI * 3) / 2 + theta); 164 | site.polygon = null; 165 | } 166 | if (x > xSize - radius) { 167 | final double theta = Math.acos((xSize - x) / radius); 168 | rangeList.subtract(0 - theta, 0 + theta); 169 | site.polygon = null; 170 | } 171 | if (z > zSize - radius) { 172 | final double theta = Math.acos((zSize - z) / radius); 173 | rangeList.subtract(Math.PI / 2 - theta, Math.PI / 2 + theta); 174 | site.polygon = null; 175 | } 176 | } 177 | 178 | private Site randomPoint(final double xSize, final double zSize, final Random random) { 179 | return new Site(random.nextDouble() * xSize, random.nextDouble() * zSize); 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /IslandCraft-Common/src/main/java/com/github/hoqhuuep/islandcraft/core/HexagonalIslandDistribution.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.core; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | import com.github.hoqhuuep.islandcraft.api.ICLocation; 7 | import com.github.hoqhuuep.islandcraft.api.ICRegion; 8 | import com.github.hoqhuuep.islandcraft.api.IslandDistribution; 9 | import com.github.hoqhuuep.islandcraft.util.StringUtils; 10 | 11 | public class HexagonalIslandDistribution implements IslandDistribution { 12 | private final int islandSize; 13 | private final int oceanSize; 14 | private final int islandSeparation; 15 | private final int twiceIslandSeparation; 16 | private final int halfIslandSeparation; 17 | private final int magicNumber1; 18 | private final int magicNumber2; 19 | private final int innerRadius; 20 | private final int outerRadius; 21 | 22 | public HexagonalIslandDistribution(final String[] args) { 23 | ICLogger.logger.info("Creating HexagonalIslandDistribution with args: " + StringUtils.join(args, " ")); 24 | if (args.length != 2) { 25 | ICLogger.logger.error("HexagonalIslandDistribution requrires 2 parameters, " + args.length + " given"); 26 | throw new IllegalArgumentException("HexagonalIslandDistribution requrires 2 parameters"); 27 | } 28 | islandSize = Integer.parseInt(args[0]); 29 | oceanSize = Integer.parseInt(args[1]); 30 | // Validate configuration values 31 | if (islandSize <= 0 || islandSize % 32 != 0) { 32 | ICLogger.logger.error("HexagonalIslandDistribution.island-size must be a positive multiple of 32"); 33 | throw new IllegalArgumentException("HexagonalIslandDistribution.island-size must be a positive multiple of 32"); 34 | } 35 | if (oceanSize <= 0 || oceanSize % 32 != 0) { 36 | ICLogger.logger.error("HexagonalIslandDistribution.ocean-size must be a positive multiple of 32"); 37 | throw new IllegalArgumentException("HexagonalIslandDistribution.ocean-size must be a positive multiple of 32"); 38 | } 39 | islandSeparation = islandSize + oceanSize; 40 | twiceIslandSeparation = islandSeparation * 2; 41 | halfIslandSeparation = islandSeparation / 2; 42 | innerRadius = islandSize / 2; 43 | outerRadius = innerRadius + oceanSize; 44 | magicNumber1 = outerRadius - oceanSize / 2; 45 | magicNumber2 = magicNumber1 + oceanSize; 46 | } 47 | 48 | @Override 49 | public ICLocation getCenterAt(int x, int z, final long worldSeed) { 50 | // xPrime, zPrime = shift the coordinate system so that 0, 0 is top-left 51 | // of spawn island 52 | // xRelative, zRelative = coordinates relative to top-left of nearest 53 | // island 54 | // row, column = nearest island 55 | final int zPrime = z + islandSize / 2; 56 | final int zRelative = ifloormod(zPrime, islandSeparation); 57 | if (zRelative >= islandSize) { 58 | return null; 59 | } 60 | final int row = ifloordiv(zPrime, islandSeparation); 61 | final int xPrime = (row % 2 == 0) ? (x + islandSize / 2) : (x + (islandSize + islandSeparation) / 2); 62 | final int xRelative = ifloormod(xPrime, islandSeparation); 63 | if (xRelative >= islandSize) { 64 | return null; 65 | } 66 | final int column = ifloordiv(xPrime, islandSeparation); 67 | return getCenter(row, column); 68 | } 69 | 70 | @Override 71 | public Set getCentersAt(int x, int z, final long worldSeed) { 72 | // Numbers represent how many island regions a location overlaps. 73 | // Arrows point towards the centers of the overlapped regions. 74 | // @-------+-----------+-------+-----------+ 75 | // |...^...|.....^.....|..\./..|.....^.....| 76 | // |...3...|.....2.....|...3...|.....2.....| 77 | // |../.\..|.....v.....|...v...|.....v.....| 78 | // +-------+-----------+-------+-----------+ 79 | // |.......|...............................| 80 | // |.......|...............................| 81 | // |.......|...............................| 82 | // |.......|...............................| 83 | // |.......|...............................| 84 | // |.......|...............................| 85 | // |..<2>..|...............#...............| 86 | // |.......|...............................| 87 | // |.......|...............................| 88 | // |.......|...............................| 89 | // |.......|...............................| 90 | // |.......|...............................| 91 | // |.......|...............................| 92 | // +-------+-----------+-------+-----------+ 93 | // |..\./..|.....^.....|...^...|.....^.....| 94 | // |...3...|.....2.....|...3...|.....2.....| 95 | // |...v...|.....v.....|../.\..|.....v.....| 96 | // +-------+-----------+-------+-----------+ 97 | // |...................|.......|...........| 98 | // |...................|.......|...........| 99 | // |...................|.......|...........| 100 | // |...................|.......|...........| 101 | // |...................|.......|...........| 102 | // |...................|.......|...........| 103 | // |...1...............|..<2>..|.......1>..| 104 | // |...................|.......|...........| 105 | // |...................|.......|...........| 106 | // |...................|.......|...........| 107 | // |...................|.......|...........| 108 | // |...................|.......|...........| 109 | // |...................|.......|...........| 110 | // +-------------------+-------+-----------+ 111 | // # relative to @ 112 | final int xPrime = x + outerRadius; 113 | final int zPrime = z + outerRadius; 114 | // # relative to world origin 115 | final int absoluteHashX = ifloordiv(xPrime, islandSeparation) * islandSeparation; 116 | final int absoluteHashZ = ifloordiv(zPrime, twiceIslandSeparation) * twiceIslandSeparation; 117 | // Point to test relative to @ 118 | final int relativeX = xPrime - absoluteHashX; 119 | final int relativeZ = zPrime - absoluteHashZ; 120 | final Set result = new HashSet(3); 121 | // Top 122 | if (relativeZ < oceanSize) { 123 | final int centerZ = absoluteHashZ - islandSeparation; 124 | // Left 125 | if (relativeX < magicNumber2) { 126 | final int centerX = absoluteHashX - halfIslandSeparation; 127 | result.add(getCenter(centerX, centerZ)); 128 | } 129 | // Right 130 | if (relativeX >= magicNumber1) { 131 | final int centerX = absoluteHashX + halfIslandSeparation; 132 | result.add(getCenter(centerX, centerZ)); 133 | } 134 | } 135 | // Middle 136 | if (relativeZ < islandSeparation + oceanSize) { 137 | // Left 138 | if (relativeX < oceanSize) { 139 | final int centerX = absoluteHashX - islandSeparation; 140 | result.add(getCenter(centerX, absoluteHashZ)); 141 | } 142 | // Right 143 | result.add(getCenter(absoluteHashX, absoluteHashZ)); 144 | } 145 | // Bottom 146 | if (relativeZ >= islandSeparation) { 147 | final int centerZ = absoluteHashZ + islandSeparation; 148 | // Left 149 | if (relativeX < magicNumber2) { 150 | final int centerX = absoluteHashX - halfIslandSeparation; 151 | result.add(getCenter(centerX, centerZ)); 152 | } 153 | // Right 154 | if (relativeX >= magicNumber1) { 155 | final int centerX = absoluteHashX + halfIslandSeparation; 156 | result.add(getCenter(centerX, centerZ)); 157 | } 158 | } 159 | return result; 160 | } 161 | 162 | @Override 163 | public ICRegion getInnerRegion(final ICLocation center, final long worldSeed) { 164 | final int centerX = center.getX(); 165 | final int centerZ = center.getZ(); 166 | if (!isCenter(centerX, centerZ)) { 167 | return null; 168 | } 169 | return new ICRegion(new ICLocation(centerX - innerRadius, centerZ - innerRadius), new ICLocation(centerX + innerRadius, centerZ + innerRadius)); 170 | } 171 | 172 | @Override 173 | public ICRegion getOuterRegion(final ICLocation center, final long worldSeed) { 174 | final int centerX = center.getX(); 175 | final int centerZ = center.getZ(); 176 | if (!isCenter(centerX, centerZ)) { 177 | return null; 178 | } 179 | return new ICRegion(new ICLocation(centerX - outerRadius, centerZ - outerRadius), new ICLocation(centerX + outerRadius, centerZ + outerRadius)); 180 | } 181 | 182 | private ICLocation getCenter(final int row, final int column) { 183 | final int centerZ = row * islandSeparation; 184 | final int centerX; 185 | if (row % 2 == 0) { 186 | centerX = column * islandSeparation; 187 | } else { 188 | centerX = column * islandSeparation - islandSeparation / 2; 189 | } 190 | return new ICLocation(centerX, centerZ); 191 | } 192 | 193 | private boolean isCenter(final int centerX, final int centerZ) { 194 | if (ifloormod(centerZ, islandSeparation) != 0) { 195 | return false; 196 | } 197 | final int row = ifloordiv(centerZ, islandSeparation); 198 | if (row % 2 == 0) { 199 | return ifloormod(centerX, islandSeparation) == 0; 200 | } 201 | return ifloormod(centerX, islandSeparation) == halfIslandSeparation; 202 | } 203 | 204 | private static int ifloordiv(int n, int d) { 205 | // Credit to Mark Dickinson 206 | // http://stackoverflow.com/a/10466453 207 | if (d >= 0) 208 | return n >= 0 ? n / d : ~(~n / d); 209 | else 210 | return n <= 0 ? n / d : (n - 1) / d - 1; 211 | } 212 | 213 | private static int ifloormod(int n, int d) { 214 | // Credit to Mark Dickinson 215 | // http://stackoverflow.com/a/10466453 216 | if (d >= 0) 217 | return n >= 0 ? n % d : d + ~(~n % d); 218 | else 219 | return n <= 0 ? n % d : d + 1 + (n - 1) % d; 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /IslandCraft-Bukkit/src/main/java/com/github/hoqhuuep/islandcraft/bukkit/IslandCraftPlugin.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.bukkit; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.logging.Level; 6 | 7 | import org.bukkit.Bukkit; 8 | import org.bukkit.World; 9 | import org.bukkit.WorldCreator; 10 | import org.bukkit.command.Command; 11 | import org.bukkit.command.CommandSender; 12 | import org.bukkit.configuration.file.FileConfiguration; 13 | import org.bukkit.entity.Player; 14 | import org.bukkit.event.Listener; 15 | import org.bukkit.plugin.java.JavaPlugin; 16 | // import org.mcstats.Metrics; 17 | 18 | import com.avaje.ebean.EbeanServer; 19 | import com.github.hoqhuuep.islandcraft.api.ICLocation; 20 | import com.github.hoqhuuep.islandcraft.api.ICRegion; 21 | import com.github.hoqhuuep.islandcraft.api.IslandCraft; 22 | import com.github.hoqhuuep.islandcraft.core.DefaultIslandCraft; 23 | import com.github.hoqhuuep.islandcraft.core.ICLogger; 24 | import com.github.hoqhuuep.islandcraft.core.IslandDatabase; 25 | import com.github.hoqhuuep.islandcraft.nms.NmsWrapper; 26 | 27 | public class IslandCraftPlugin extends JavaPlugin { 28 | 29 | private DefaultIslandCraft islandCraft = null; 30 | 31 | @Override 32 | public void onEnable() { 33 | ICLogger.logger = new JavaUtilLogger(getLogger()); 34 | 35 | // https://github.com/Hidendra/Plugin-Metrics/wiki/Usage 36 | // Temporarily disabled due to incompatibility with 1.9 37 | // try { 38 | // final Metrics metrics = new Metrics(this); 39 | // metrics.start(); 40 | // } catch (final Exception e) { 41 | // ICLogger.logger.warning("Failed to start MCStats"); 42 | // } 43 | 44 | saveDefaultConfig(); 45 | FileConfiguration config = getConfig(); 46 | if (!config.contains("config-version") || !config.isString("config-version")) { 47 | ICLogger.logger.error("No string-value for 'config-version' found in config.yml"); 48 | ICLogger.logger.error("Check for updates at http://dev.bukkit.org/bukkit-plugins/islandcraft/"); 49 | setEnabled(false); 50 | return; 51 | } 52 | final String configVersion = config.getString("config-version"); 53 | if (!configVersion.equals("1.0.0")) { 54 | ICLogger.logger.error("Incompatible config-version found in config.yml"); 55 | ICLogger.logger.error("Check for updates at http://dev.bukkit.org/bukkit-plugins/islandcraft/"); 56 | setEnabled(false); 57 | return; 58 | } 59 | 60 | if (!config.contains("verbose-logging") || !config.isBoolean("verbose-logging")) { 61 | ICLogger.logger.warning("No boolean-value for 'verbose-logging' found in config.yml"); 62 | ICLogger.logger.warning("Default value 'false' will be used"); 63 | } 64 | final boolean verboseLogging = config.getBoolean("verbose-logging", false); 65 | getLogger().setLevel(verboseLogging ? Level.ALL : Level.WARNING); 66 | 67 | final NmsWrapper nms = NmsWrapper.getInstance(getServer()); 68 | if (nms == null) { 69 | ICLogger.logger.error("IslandCraft does not currently support this CraftBukkit version"); 70 | ICLogger.logger.error("Check for updates at http://dev.bukkit.org/bukkit-plugins/islandcraft/"); 71 | setEnabled(false); 72 | return; 73 | } 74 | 75 | IslandDatabase database; 76 | try { 77 | final EbeanServer ebeanServer = EbeanServerUtil.build(this); 78 | database = new EbeanServerIslandDatabase(ebeanServer); 79 | } catch (final Exception e) { 80 | ICLogger.logger.error("Error creating EbeanServer database"); 81 | ICLogger.logger.error("Check for updates at http://dev.bukkit.org/bukkit-plugins/islandcraft/"); 82 | ICLogger.logger.error("Exception message: " + e.getMessage()); 83 | setEnabled(false); 84 | return; 85 | } 86 | 87 | try { 88 | islandCraft = new DefaultIslandCraft(); 89 | final Listener listener = new BiomeGeneratorListener(this, database, nms); 90 | getServer().getPluginManager().registerEvents(listener, this); 91 | } catch (final Exception e) { 92 | ICLogger.logger.error("Error creating or registering BiomeGeneratorListener"); 93 | ICLogger.logger.error("Check for updates at http://dev.bukkit.org/bukkit-plugins/islandcraft/"); 94 | ICLogger.logger.error("Exception message: " + e.getMessage()); 95 | setEnabled(false); 96 | return; 97 | } 98 | } 99 | 100 | @Override 101 | public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { 102 | if (sender instanceof Player) { 103 | sender.sendMessage("This command can only be executed by console!"); 104 | return false; 105 | } 106 | if (args.length == 0) { 107 | sender.sendMessage("/ic "); 108 | return false; 109 | } 110 | if ("reload".equals(args[0])) { 111 | sender.sendMessage("Reloaded IslandCraft configuration"); 112 | reloadConfig(); 113 | } else if ("create".equals(args[0])) { 114 | // ic create 2 1 ConstantBiomeDistribution IslandGeneratorAlpha 115 | if (args.length < 4) { 116 | sender.sendMessage("/ic create "); 117 | sender.sendMessage("OR"); 118 | sender.sendMessage("/ic create [distribution] [generator]"); 119 | sender.sendMessage("Note: An island size of 1 = 4 chunks"); 120 | return false; 121 | } 122 | String world = args[1]; 123 | int island; 124 | int ocean; 125 | try { 126 | island = Integer.parseInt(args[2]) * 32; 127 | ocean = Integer.parseInt(args[3]) * 32; 128 | } catch (Exception e) { 129 | sender.sendMessage("Invalid size for:"); 130 | sender.sendMessage("/ic create [distribution] [generator]"); 131 | return false; 132 | } 133 | String distribution = "SquareIslandDistribution"; 134 | String generator = "IslandGeneratorAlpha"; 135 | if (args.length > 4) { 136 | distribution = args[4]; 137 | } 138 | if (args.length > 5) { 139 | distribution = args[5]; 140 | } 141 | FileConfiguration config = getConfig(); 142 | String path = "worlds." + world; 143 | config.set(path + "." + "ocean", 144 | "com.github.hoqhuuep.islandcraft.core.ConstantBiomeDistribution DEEP_OCEAN"); 145 | config.set(path + "." + "island-distribution", 146 | "com.github.hoqhuuep.islandcraft.core." + distribution + " " + island + " " + ocean); 147 | String[] gen_types = { 148 | "com.github.hoqhuuep.islandcraft.core." + generator 149 | + " BIRCH_FOREST BIRCH_FOREST_M BIRCH_FOREST_HILLS BIRCH_FOREST_HILLS_M ~ ~ OCEAN BEACH RIVER", 150 | "com.github.hoqhuuep.islandcraft.core." + generator 151 | + " COLD_TAIGA COLD_TAIGA_M COLD_TAIGA_HILLS ~ ~ ~ OCEAN COLD_BEACH FROZEN_RIVER", 152 | "com.github.hoqhuuep.islandcraft.core." + generator 153 | + " DESERT DESERT_M DESERT_HILLS ~ ~ ~ OCEAN BEACH RIVER", 154 | "com.github.hoqhuuep.islandcraft.core." + generator 155 | + " EXTREME_HILLS EXTREME_HILLS_M EXTREME_HILLS_PLUS EXTREME_HILLS_PLUS_M EXTREME_HILLS_EDGE ~ OCEAN STONE_BEACH RIVER", 156 | "com.github.hoqhuuep.islandcraft.core." + generator 157 | + " FOREST ~ FOREST_HILLS ~ FLOWER_FOREST ~ OCEAN BEACH RIVER", 158 | "com.github.hoqhuuep.islandcraft.core." + generator 159 | + " ICE_PLAINS ~ ICE_MOUNTAINS ~ ICE_PLAINS_SPIKES ~ OCEAN FROZEN_OCEAN FROZEN_RIVER", 160 | "com.github.hoqhuuep.islandcraft.core." + generator 161 | + " JUNGLE JUNGLE_M JUNGLE_HILLS ~ JUNGLE_EDGE JUNGLE_EDGE_M OCEAN BEACH RIVER", 162 | "com.github.hoqhuuep.islandcraft.core." + generator 163 | + " MEGA_TAIGA MEGA_SPRUCE_TAIGA MEGA_TAIGA_HILLS MEGA_SPRUCE_TAIGA_HILLS ~ ~ OCEAN BEACH RIVER", 164 | "com.github.hoqhuuep.islandcraft.core." + generator 165 | + " MESA MESA_BRYCE MESA_PLATEAU MESA_PLATEAU_M MESA_PLATEAU_F MESA_PLATEAU_F_M OCEAN MESA RIVER", 166 | "com.github.hoqhuuep.islandcraft.core." + generator 167 | + " MUSHROOM_ISLAND ~ ~ ~ ~ ~ OCEAN MUSHROOM_ISLAND_SHORE RIVER", 168 | "com.github.hoqhuuep.islandcraft.core." + generator 169 | + " PLAINS ~ SUNFLOWER_PLAINS ~ ~ ~ OCEAN BEACH RIVER", 170 | "com.github.hoqhuuep.islandcraft.core." + generator 171 | + " ROOFED_FOREST ROOFED_FOREST_M ~ ~ ~ ~ OCEAN BEACH RIVER", 172 | "com.github.hoqhuuep.islandcraft.core." + generator 173 | + " SAVANNA SAVANNA_M SAVANNA_PLATEAU SAVANNA_PLATEAU_M ~ ~ OCEAN BEACH RIVER", 174 | "com.github.hoqhuuep.islandcraft.core." + generator 175 | + " SWAMPLAND SWAMPLAND_M ~ ~ ~ ~ OCEAN BEACH RIVER", 176 | "com.github.hoqhuuep.islandcraft.core." + generator 177 | + " TAIGA TAIGA_M TAIGA_HILLS ~ ~ ~ OCEAN BEACH RIVER" }; 178 | 179 | config.set(path + "." + "island-generators", gen_types); 180 | 181 | sender.sendMessage("Saving configuration!"); 182 | saveConfig(); 183 | reloadConfig(); 184 | sender.sendMessage("Generating world; please wait..."); 185 | if ((Bukkit.getPluginManager().getPlugin("Multiverse-Core") != null) 186 | && Bukkit.getPluginManager().getPlugin("Multiverse-Core").isEnabled()) { 187 | Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), 188 | "mv create " + world + " normal"); 189 | } else { 190 | if ((Bukkit.getPluginManager().getPlugin("MultiWorld") != null) 191 | && Bukkit.getPluginManager().getPlugin("MultiWorld").isEnabled()) { 192 | Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mw create " + world); 193 | } else { 194 | Bukkit.createWorld(new WorldCreator(world).environment(World.Environment.NORMAL)); 195 | } 196 | } 197 | sender.sendMessage("Done!"); 198 | } else { 199 | sender.sendMessage("/ic "); 200 | } 201 | return true; 202 | } 203 | 204 | @Override 205 | public void onDisable() { 206 | ICLogger.logger = null; 207 | } 208 | 209 | public List> getDatabaseClasses() { 210 | final Class[] classes = { EbeanServerIslandDatabase.IslandBean.class, 211 | EbeanServerIslandDatabase.IslandPK.class }; 212 | return Arrays.asList(classes); 213 | } 214 | 215 | public IslandCraft getIslandCraft() { 216 | return islandCraft; 217 | } 218 | 219 | private static final int BLOCKS_PER_CHUNK = 16; 220 | 221 | public void regenerate(final World world, final ICRegion region) { 222 | final ICLocation min = region.getMin(); 223 | final ICLocation max = region.getMax(); 224 | final int minX = min.getX() / BLOCKS_PER_CHUNK; 225 | final int minZ = min.getZ() / BLOCKS_PER_CHUNK; 226 | final int maxX = max.getX() / BLOCKS_PER_CHUNK; 227 | final int maxZ = max.getZ() / BLOCKS_PER_CHUNK; 228 | // Must loop from high to low for trees to generate correctly 229 | for (int x = maxX - 1; x >= minX; --x) { 230 | for (int z = maxZ - 1; z >= minZ; --z) { 231 | // TODO queue these? 232 | world.regenerateChunk(x, z); 233 | } 234 | } 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_7_R1/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_7_R1/CustomWorldChunkManager.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_7_R1; 2 | 3 | import java.util.EnumMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.Random; 7 | 8 | import net.minecraft.server.v1_7_R1.BiomeBase; 9 | import net.minecraft.server.v1_7_R1.BiomeCache; 10 | import net.minecraft.server.v1_7_R1.ChunkPosition; 11 | import net.minecraft.server.v1_7_R1.WorldChunkManager; 12 | 13 | import com.github.hoqhuuep.islandcraft.api.ICBiome; 14 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 15 | 16 | public class CustomWorldChunkManager extends WorldChunkManager { 17 | private static final Map biomeMap = new EnumMap(ICBiome.class); 18 | 19 | private static final BiomeBase special(final BiomeBase biome) { 20 | return BiomeBase.getBiome(biome.id + 128); 21 | } 22 | 23 | static { 24 | biomeMap.put(ICBiome.BEACH, BiomeBase.BEACH); 25 | biomeMap.put(ICBiome.BIRCH_FOREST, BiomeBase.BIRCH_FOREST); 26 | biomeMap.put(ICBiome.BIRCH_FOREST_HILLS, BiomeBase.BIRCH_FOREST_HILLS); 27 | biomeMap.put(ICBiome.BIRCH_FOREST_HILLS_M, special(BiomeBase.BIRCH_FOREST_HILLS)); 28 | biomeMap.put(ICBiome.BIRCH_FOREST_M, special(BiomeBase.BIRCH_FOREST)); 29 | biomeMap.put(ICBiome.COLD_BEACH, BiomeBase.COLD_BEACH); 30 | biomeMap.put(ICBiome.COLD_TAIGA, BiomeBase.COLD_TAIGA); 31 | biomeMap.put(ICBiome.COLD_TAIGA_HILLS, BiomeBase.COLD_TAIGA_HILLS); 32 | biomeMap.put(ICBiome.COLD_TAIGA_M, special(BiomeBase.COLD_TAIGA)); 33 | biomeMap.put(ICBiome.DEEP_OCEAN, BiomeBase.DEEP_OCEAN); 34 | biomeMap.put(ICBiome.DESERT, BiomeBase.DESERT); 35 | biomeMap.put(ICBiome.DESERT_HILLS, BiomeBase.DESERT_HILLS); 36 | biomeMap.put(ICBiome.DESERT_M, special(BiomeBase.DESERT)); 37 | biomeMap.put(ICBiome.END, BiomeBase.SKY); 38 | biomeMap.put(ICBiome.EXTREME_HILLS, BiomeBase.EXTREME_HILLS); 39 | biomeMap.put(ICBiome.EXTREME_HILLS_EDGE, BiomeBase.SMALL_MOUNTAINS); 40 | biomeMap.put(ICBiome.EXTREME_HILLS_M, special(BiomeBase.EXTREME_HILLS)); 41 | biomeMap.put(ICBiome.EXTREME_HILLS_PLUS, BiomeBase.EXTREME_HILLS_PLUS); 42 | biomeMap.put(ICBiome.EXTREME_HILLS_PLUS_M, special(BiomeBase.EXTREME_HILLS_PLUS)); 43 | biomeMap.put(ICBiome.FLOWER_FOREST, special(BiomeBase.FOREST)); 44 | biomeMap.put(ICBiome.FOREST, BiomeBase.FOREST); 45 | biomeMap.put(ICBiome.FOREST_HILLS, BiomeBase.FOREST_HILLS); 46 | biomeMap.put(ICBiome.FROZEN_OCEAN, BiomeBase.FROZEN_OCEAN); 47 | biomeMap.put(ICBiome.FROZEN_RIVER, BiomeBase.FROZEN_RIVER); 48 | biomeMap.put(ICBiome.ICE_MOUNTAINS, BiomeBase.ICE_MOUNTAINS); 49 | biomeMap.put(ICBiome.ICE_PLAINS, BiomeBase.ICE_PLAINS); 50 | biomeMap.put(ICBiome.ICE_PLAINS_SPIKES, special(BiomeBase.ICE_PLAINS)); 51 | biomeMap.put(ICBiome.JUNGLE, BiomeBase.JUNGLE); 52 | biomeMap.put(ICBiome.JUNGLE_EDGE, BiomeBase.JUNGLE_EDGE); 53 | biomeMap.put(ICBiome.JUNGLE_HILLS, BiomeBase.JUNGLE_HILLS); 54 | biomeMap.put(ICBiome.JUNGLE_M, special(BiomeBase.JUNGLE)); 55 | biomeMap.put(ICBiome.JUNGLE_EDGE_M, special(BiomeBase.JUNGLE_EDGE)); 56 | biomeMap.put(ICBiome.MEGA_SPRUCE_TAIGA, special(BiomeBase.MEGA_TAIGA)); 57 | biomeMap.put(ICBiome.MEGA_SPRUCE_TAIGA_HILLS, special(BiomeBase.MEGA_TAIGA_HILLS)); 58 | biomeMap.put(ICBiome.MEGA_TAIGA, BiomeBase.MEGA_TAIGA); 59 | biomeMap.put(ICBiome.MEGA_TAIGA_HILLS, BiomeBase.MEGA_TAIGA_HILLS); 60 | biomeMap.put(ICBiome.MESA, BiomeBase.MESA); 61 | biomeMap.put(ICBiome.MESA_BRYCE, special(BiomeBase.MESA)); 62 | biomeMap.put(ICBiome.MESA_PLATEAU, BiomeBase.MESA_PLATEAU); 63 | biomeMap.put(ICBiome.MESA_PLATEAU_F, BiomeBase.MESA_PLATEAU_F); 64 | biomeMap.put(ICBiome.MESA_PLATEAU_F_M, special(BiomeBase.MESA_PLATEAU_F)); 65 | biomeMap.put(ICBiome.MESA_PLATEAU_M, special(BiomeBase.MESA_PLATEAU)); 66 | biomeMap.put(ICBiome.MUSHROOM_ISLAND, BiomeBase.MUSHROOM_ISLAND); 67 | biomeMap.put(ICBiome.MUSHROOM_ISLAND_SHORE, BiomeBase.MUSHROOM_SHORE); 68 | biomeMap.put(ICBiome.NETHER, BiomeBase.HELL); 69 | biomeMap.put(ICBiome.OCEAN, BiomeBase.OCEAN); 70 | biomeMap.put(ICBiome.PLAINS, BiomeBase.PLAINS); 71 | biomeMap.put(ICBiome.RIVER, BiomeBase.RIVER); 72 | biomeMap.put(ICBiome.ROOFED_FOREST, BiomeBase.ROOFED_FOREST); 73 | biomeMap.put(ICBiome.ROOFED_FOREST_M, special(BiomeBase.ROOFED_FOREST)); 74 | biomeMap.put(ICBiome.SAVANNA, BiomeBase.SAVANNA); 75 | biomeMap.put(ICBiome.SAVANNA_M, special(BiomeBase.SAVANNA)); 76 | biomeMap.put(ICBiome.SAVANNA_PLATEAU, BiomeBase.SAVANNA_PLATEAU); 77 | biomeMap.put(ICBiome.SAVANNA_PLATEAU_M, special(BiomeBase.SAVANNA_PLATEAU)); 78 | biomeMap.put(ICBiome.STONE_BEACH, BiomeBase.STONE_BEACH); 79 | biomeMap.put(ICBiome.SUNFLOWER_PLAINS, special(BiomeBase.PLAINS)); 80 | biomeMap.put(ICBiome.SWAMPLAND, BiomeBase.SWAMPLAND); 81 | biomeMap.put(ICBiome.SWAMPLAND_M, special(BiomeBase.SWAMPLAND)); 82 | biomeMap.put(ICBiome.TAIGA, BiomeBase.TAIGA); 83 | biomeMap.put(ICBiome.TAIGA_HILLS, BiomeBase.TAIGA_HILLS); 84 | biomeMap.put(ICBiome.TAIGA_M, special(BiomeBase.TAIGA)); 85 | } 86 | 87 | private final BiomeCache biomeCache; 88 | private final BiomeGenerator biomeGenerator; 89 | 90 | public CustomWorldChunkManager(final BiomeGenerator biomeGenerator) { 91 | this.biomeGenerator = biomeGenerator; 92 | this.biomeCache = new BiomeCache(this); 93 | } 94 | 95 | /** Returns a list of biome's which are valid for spawn */ 96 | @Override 97 | @SuppressWarnings("rawtypes") 98 | public List a() { 99 | return super.a(); 100 | } 101 | 102 | /** Returns the biome at a position. Used for various things. */ 103 | @Override 104 | public BiomeBase getBiome(final int x, final int z) { 105 | // Get from cache 106 | return this.biomeCache.b(x, z); 107 | } 108 | 109 | /** Used in creating ChunkSnapshot's */ 110 | @Override 111 | public float[] getWetness(float[] result, final int x, final int z, int xSize, final int zSize) { 112 | // Create result array if given one is insufficient 113 | if (result == null || result.length < xSize * zSize) { 114 | // In reality result is always null 115 | result = new float[xSize * zSize]; 116 | } 117 | // In reality size is always 1 chunk's worth 118 | final BiomeBase[] biomes = a(null, x, z, xSize, zSize, false); 119 | for (int i = 0; i < xSize * zSize; i++) { 120 | final float wetness = biomes[i].h() / 65536.0F; 121 | if (wetness > 1.0F) { 122 | result[i] = 1.0F; 123 | } else { 124 | result[i] = wetness; 125 | } 126 | } 127 | return result; 128 | } 129 | 130 | /** Used for height map and temperature */ 131 | @Override 132 | public BiomeBase[] getBiomes(BiomeBase[] result, final int xMin, final int zMin, final int xSize, final int zSize) { 133 | // Create result array if given one is insufficient 134 | if (result == null || result.length < xSize * zSize) { 135 | result = new BiomeBase[xSize * zSize]; 136 | } 137 | // 1 in every 4 138 | for (int i = 0; i < xSize * zSize; ++i) { 139 | final int x = (xMin + (i % xSize)) << 2; 140 | final int z = (zMin + (i / xSize)) << 2; 141 | final ICBiome biome = biomeGenerator.generateBiome(x, z); 142 | result[i] = biomeMap.get(biome); 143 | } 144 | return result; 145 | } 146 | 147 | /** Used in chunk creation */ 148 | @Override 149 | public BiomeBase[] getBiomeBlock(final BiomeBase[] array, final int x, final int z, final int xSize, final int zSize) { 150 | return a(array, x, z, xSize, zSize, true); 151 | } 152 | 153 | /** Only used in above method... and getWetness */ 154 | @Override 155 | public BiomeBase[] a(BiomeBase[] result, final int xMin, final int zMin, final int xSize, final int zSize, final boolean useCache) { 156 | // Create result array if given one is insufficient 157 | if (result == null || result.length < xSize * zSize) { 158 | // Happens for nether, end, and flat worlds... 159 | result = new BiomeBase[xSize * zSize]; 160 | } 161 | // More efficient handling of whole chunk 162 | if (xSize == 16 && zSize == 16 && (xMin & 0xF) == 0 && (zMin & 0xF) == 0) { 163 | if (useCache) { 164 | // Happens most of the time 165 | final BiomeBase[] biomes = this.biomeCache.d(xMin, zMin); 166 | System.arraycopy(biomes, 0, result, 0, xSize * zSize); 167 | return result; 168 | } 169 | // This only happens in getWetness above 170 | final ICBiome[] temp = biomeGenerator.generateChunkBiomes(xMin, zMin); 171 | for (int i = 0; i < xSize * zSize; ++i) { 172 | result[i] = biomeMap.get(temp[i]); 173 | } 174 | return result; 175 | } 176 | // In reality this never happens... 177 | for (int x = 0; x < xSize; ++x) { 178 | for (int z = 0; z < zSize; ++z) { 179 | final ICBiome temp = biomeGenerator.generateBiome(xMin + x, zMin + z); 180 | result[x + z * xSize] = biomeMap.get(temp); 181 | } 182 | } 183 | return result; 184 | } 185 | 186 | /** 187 | * Returns true if all biome's in area are in allowedBiomes. x, z and radius 188 | * are in blocks. Used for checking where a village can go. 189 | */ 190 | @Override 191 | public boolean a(final int x, final int z, final int radius, @SuppressWarnings("rawtypes") final List allowedBiomes) { 192 | // Convert center and radius to minimum and size 193 | final int xMin = (x - radius) >> 2; 194 | final int zMin = (z - radius) >> 2; 195 | final int xMax = (x + radius) >> 2; 196 | final int zMax = (z + radius) >> 2; 197 | final int xSize = xMax - xMin + 1; 198 | final int zSize = zMax - zMin + 1; 199 | // Generate biome's 200 | final BiomeBase[] biomes = getBiomes(null, xMin, zMin, xSize, zSize); 201 | // Make sure all biomes are allowed 202 | for (int i = 0; i < xSize * zSize; i++) { 203 | if (!allowedBiomes.contains(biomes[i])) { 204 | return false; 205 | } 206 | } 207 | return true; 208 | } 209 | 210 | /** 211 | * Returns random position within biome if it can be found in given area. 212 | * Otherwise null. Used for initial guess at spawn point and stronghold 213 | * locations. 214 | */ 215 | @Override 216 | public ChunkPosition a(final int x, final int z, final int radius, @SuppressWarnings("rawtypes") final List allowedBiomes, final Random random) { 217 | // Convert center and radius to minimum and size 218 | final int xMin = (x - radius) >> 2; 219 | final int zMin = (z - radius) >> 2; 220 | final int xMax = (x + radius) >> 2; 221 | final int zMax = (z + radius) >> 2; 222 | final int xSize = xMax - xMin + 1; 223 | final int zSize = zMax - zMin + 1; 224 | // Generate biome's 225 | final BiomeBase[] biomes = getBiomes(null, xMin, zMin, xSize, zSize); 226 | ChunkPosition result = null; 227 | int count = 0; 228 | for (int i = 0; i < xSize * zSize; i++) { 229 | final int xPosition = (xMin + (i % xSize)) << 2; 230 | final int zPosition = (zMin + (i / xSize)) << 2; 231 | if (allowedBiomes.contains(biomes[i]) && (result == null || random.nextInt(count + 1) == 0)) { 232 | result = new ChunkPosition(xPosition, 0, zPosition); 233 | count++; 234 | } 235 | } 236 | return result; 237 | } 238 | 239 | /** Cleans up biomeCache, called in tick */ 240 | @Override 241 | public void b() { 242 | // Clean up biomeCache 243 | biomeCache.a(); 244 | biomeGenerator.cleanupCache(); 245 | } 246 | } 247 | -------------------------------------------------------------------------------- /IslandCraft-NMS-v1_7_R2/src/main/java/com/github/hoqhuuep/islandcraft/nms/v1_7_R2/CustomWorldChunkManager.java: -------------------------------------------------------------------------------- 1 | package com.github.hoqhuuep.islandcraft.nms.v1_7_R2; 2 | 3 | import java.util.EnumMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.Random; 7 | 8 | import net.minecraft.server.v1_7_R2.BiomeBase; 9 | import net.minecraft.server.v1_7_R2.BiomeCache; 10 | import net.minecraft.server.v1_7_R2.ChunkPosition; 11 | import net.minecraft.server.v1_7_R2.WorldChunkManager; 12 | 13 | import com.github.hoqhuuep.islandcraft.api.ICBiome; 14 | import com.github.hoqhuuep.islandcraft.nms.BiomeGenerator; 15 | 16 | public class CustomWorldChunkManager extends WorldChunkManager { 17 | private static final Map biomeMap = new EnumMap(ICBiome.class); 18 | 19 | private static final BiomeBase special(final BiomeBase biome) { 20 | return BiomeBase.getBiome(biome.id + 128); 21 | } 22 | 23 | static { 24 | biomeMap.put(ICBiome.BEACH, BiomeBase.BEACH); 25 | biomeMap.put(ICBiome.BIRCH_FOREST, BiomeBase.BIRCH_FOREST); 26 | biomeMap.put(ICBiome.BIRCH_FOREST_HILLS, BiomeBase.BIRCH_FOREST_HILLS); 27 | biomeMap.put(ICBiome.BIRCH_FOREST_HILLS_M, special(BiomeBase.BIRCH_FOREST_HILLS)); 28 | biomeMap.put(ICBiome.BIRCH_FOREST_M, special(BiomeBase.BIRCH_FOREST)); 29 | biomeMap.put(ICBiome.COLD_BEACH, BiomeBase.COLD_BEACH); 30 | biomeMap.put(ICBiome.COLD_TAIGA, BiomeBase.COLD_TAIGA); 31 | biomeMap.put(ICBiome.COLD_TAIGA_HILLS, BiomeBase.COLD_TAIGA_HILLS); 32 | biomeMap.put(ICBiome.COLD_TAIGA_M, special(BiomeBase.COLD_TAIGA)); 33 | biomeMap.put(ICBiome.DEEP_OCEAN, BiomeBase.DEEP_OCEAN); 34 | biomeMap.put(ICBiome.DESERT, BiomeBase.DESERT); 35 | biomeMap.put(ICBiome.DESERT_HILLS, BiomeBase.DESERT_HILLS); 36 | biomeMap.put(ICBiome.DESERT_M, special(BiomeBase.DESERT)); 37 | biomeMap.put(ICBiome.END, BiomeBase.SKY); 38 | biomeMap.put(ICBiome.EXTREME_HILLS, BiomeBase.EXTREME_HILLS); 39 | biomeMap.put(ICBiome.EXTREME_HILLS_EDGE, BiomeBase.SMALL_MOUNTAINS); 40 | biomeMap.put(ICBiome.EXTREME_HILLS_M, special(BiomeBase.EXTREME_HILLS)); 41 | biomeMap.put(ICBiome.EXTREME_HILLS_PLUS, BiomeBase.EXTREME_HILLS_PLUS); 42 | biomeMap.put(ICBiome.EXTREME_HILLS_PLUS_M, special(BiomeBase.EXTREME_HILLS_PLUS)); 43 | biomeMap.put(ICBiome.FLOWER_FOREST, special(BiomeBase.FOREST)); 44 | biomeMap.put(ICBiome.FOREST, BiomeBase.FOREST); 45 | biomeMap.put(ICBiome.FOREST_HILLS, BiomeBase.FOREST_HILLS); 46 | biomeMap.put(ICBiome.FROZEN_OCEAN, BiomeBase.FROZEN_OCEAN); 47 | biomeMap.put(ICBiome.FROZEN_RIVER, BiomeBase.FROZEN_RIVER); 48 | biomeMap.put(ICBiome.ICE_MOUNTAINS, BiomeBase.ICE_MOUNTAINS); 49 | biomeMap.put(ICBiome.ICE_PLAINS, BiomeBase.ICE_PLAINS); 50 | biomeMap.put(ICBiome.ICE_PLAINS_SPIKES, special(BiomeBase.ICE_PLAINS)); 51 | biomeMap.put(ICBiome.JUNGLE, BiomeBase.JUNGLE); 52 | biomeMap.put(ICBiome.JUNGLE_EDGE, BiomeBase.JUNGLE_EDGE); 53 | biomeMap.put(ICBiome.JUNGLE_HILLS, BiomeBase.JUNGLE_HILLS); 54 | biomeMap.put(ICBiome.JUNGLE_M, special(BiomeBase.JUNGLE)); 55 | biomeMap.put(ICBiome.JUNGLE_EDGE_M, special(BiomeBase.JUNGLE_EDGE)); 56 | biomeMap.put(ICBiome.MEGA_SPRUCE_TAIGA, special(BiomeBase.MEGA_TAIGA)); 57 | biomeMap.put(ICBiome.MEGA_SPRUCE_TAIGA_HILLS, special(BiomeBase.MEGA_TAIGA_HILLS)); 58 | biomeMap.put(ICBiome.MEGA_TAIGA, BiomeBase.MEGA_TAIGA); 59 | biomeMap.put(ICBiome.MEGA_TAIGA_HILLS, BiomeBase.MEGA_TAIGA_HILLS); 60 | biomeMap.put(ICBiome.MESA, BiomeBase.MESA); 61 | biomeMap.put(ICBiome.MESA_BRYCE, special(BiomeBase.MESA)); 62 | biomeMap.put(ICBiome.MESA_PLATEAU, BiomeBase.MESA_PLATEAU); 63 | biomeMap.put(ICBiome.MESA_PLATEAU_F, BiomeBase.MESA_PLATEAU_F); 64 | biomeMap.put(ICBiome.MESA_PLATEAU_F_M, special(BiomeBase.MESA_PLATEAU_F)); 65 | biomeMap.put(ICBiome.MESA_PLATEAU_M, special(BiomeBase.MESA_PLATEAU)); 66 | biomeMap.put(ICBiome.MUSHROOM_ISLAND, BiomeBase.MUSHROOM_ISLAND); 67 | biomeMap.put(ICBiome.MUSHROOM_ISLAND_SHORE, BiomeBase.MUSHROOM_SHORE); 68 | biomeMap.put(ICBiome.NETHER, BiomeBase.HELL); 69 | biomeMap.put(ICBiome.OCEAN, BiomeBase.OCEAN); 70 | biomeMap.put(ICBiome.PLAINS, BiomeBase.PLAINS); 71 | biomeMap.put(ICBiome.RIVER, BiomeBase.RIVER); 72 | biomeMap.put(ICBiome.ROOFED_FOREST, BiomeBase.ROOFED_FOREST); 73 | biomeMap.put(ICBiome.ROOFED_FOREST_M, special(BiomeBase.ROOFED_FOREST)); 74 | biomeMap.put(ICBiome.SAVANNA, BiomeBase.SAVANNA); 75 | biomeMap.put(ICBiome.SAVANNA_M, special(BiomeBase.SAVANNA)); 76 | biomeMap.put(ICBiome.SAVANNA_PLATEAU, BiomeBase.SAVANNA_PLATEAU); 77 | biomeMap.put(ICBiome.SAVANNA_PLATEAU_M, special(BiomeBase.SAVANNA_PLATEAU)); 78 | biomeMap.put(ICBiome.STONE_BEACH, BiomeBase.STONE_BEACH); 79 | biomeMap.put(ICBiome.SUNFLOWER_PLAINS, special(BiomeBase.PLAINS)); 80 | biomeMap.put(ICBiome.SWAMPLAND, BiomeBase.SWAMPLAND); 81 | biomeMap.put(ICBiome.SWAMPLAND_M, special(BiomeBase.SWAMPLAND)); 82 | biomeMap.put(ICBiome.TAIGA, BiomeBase.TAIGA); 83 | biomeMap.put(ICBiome.TAIGA_HILLS, BiomeBase.TAIGA_HILLS); 84 | biomeMap.put(ICBiome.TAIGA_M, special(BiomeBase.TAIGA)); 85 | } 86 | 87 | private final BiomeCache biomeCache; 88 | private final BiomeGenerator biomeGenerator; 89 | 90 | public CustomWorldChunkManager(final BiomeGenerator biomeGenerator) { 91 | this.biomeGenerator = biomeGenerator; 92 | this.biomeCache = new BiomeCache(this); 93 | } 94 | 95 | /** Returns a list of biome's which are valid for spawn */ 96 | @Override 97 | @SuppressWarnings("rawtypes") 98 | public List a() { 99 | return super.a(); 100 | } 101 | 102 | /** Returns the biome at a position. Used for various things. */ 103 | @Override 104 | public BiomeBase getBiome(final int x, final int z) { 105 | // Get from cache 106 | return this.biomeCache.b(x, z); 107 | } 108 | 109 | /** Used in creating ChunkSnapshot's */ 110 | @Override 111 | public float[] getWetness(float[] result, final int x, final int z, int xSize, final int zSize) { 112 | // Create result array if given one is insufficient 113 | if (result == null || result.length < xSize * zSize) { 114 | // In reality result is always null 115 | result = new float[xSize * zSize]; 116 | } 117 | // In reality size is always 1 chunk's worth 118 | final BiomeBase[] biomes = a(null, x, z, xSize, zSize, false); 119 | for (int i = 0; i < xSize * zSize; i++) { 120 | final float wetness = biomes[i].h() / 65536.0F; 121 | if (wetness > 1.0F) { 122 | result[i] = 1.0F; 123 | } else { 124 | result[i] = wetness; 125 | } 126 | } 127 | return result; 128 | } 129 | 130 | /** Used for height map and temperature */ 131 | @Override 132 | public BiomeBase[] getBiomes(BiomeBase[] result, final int xMin, final int zMin, final int xSize, final int zSize) { 133 | // Create result array if given one is insufficient 134 | if (result == null || result.length < xSize * zSize) { 135 | result = new BiomeBase[xSize * zSize]; 136 | } 137 | // 1 in every 4 138 | for (int i = 0; i < xSize * zSize; ++i) { 139 | final int x = (xMin + (i % xSize)) << 2; 140 | final int z = (zMin + (i / xSize)) << 2; 141 | final ICBiome biome = biomeGenerator.generateBiome(x, z); 142 | result[i] = biomeMap.get(biome); 143 | } 144 | return result; 145 | } 146 | 147 | /** Used in chunk creation */ 148 | @Override 149 | public BiomeBase[] getBiomeBlock(final BiomeBase[] array, final int x, final int z, final int xSize, final int zSize) { 150 | return a(array, x, z, xSize, zSize, true); 151 | } 152 | 153 | /** Only used in above method... and getWetness */ 154 | @Override 155 | public BiomeBase[] a(BiomeBase[] result, final int xMin, final int zMin, final int xSize, final int zSize, final boolean useCache) { 156 | // Create result array if given one is insufficient 157 | if (result == null || result.length < xSize * zSize) { 158 | // Happens for nether, end, and flat worlds... 159 | result = new BiomeBase[xSize * zSize]; 160 | } 161 | // More efficient handling of whole chunk 162 | if (xSize == 16 && zSize == 16 && (xMin & 0xF) == 0 && (zMin & 0xF) == 0) { 163 | if (useCache) { 164 | // Happens most of the time 165 | final BiomeBase[] biomes = this.biomeCache.d(xMin, zMin); 166 | System.arraycopy(biomes, 0, result, 0, xSize * zSize); 167 | return result; 168 | } 169 | // This only happens in getWetness above 170 | final ICBiome[] temp = biomeGenerator.generateChunkBiomes(xMin, zMin); 171 | for (int i = 0; i < xSize * zSize; ++i) { 172 | result[i] = biomeMap.get(temp[i]); 173 | } 174 | return result; 175 | } 176 | // In reality this never happens... 177 | for (int x = 0; x < xSize; ++x) { 178 | for (int z = 0; z < zSize; ++z) { 179 | final ICBiome temp = biomeGenerator.generateBiome(xMin + x, zMin + z); 180 | result[x + z * xSize] = biomeMap.get(temp); 181 | } 182 | } 183 | return result; 184 | } 185 | 186 | /** 187 | * Returns true if all biome's in area are in allowedBiomes. x, z and radius 188 | * are in blocks. Used for checking where a village can go. 189 | */ 190 | @Override 191 | public boolean a(final int x, final int z, final int radius, @SuppressWarnings("rawtypes") final List allowedBiomes) { 192 | // Convert center and radius to minimum and size 193 | final int xMin = (x - radius) >> 2; 194 | final int zMin = (z - radius) >> 2; 195 | final int xMax = (x + radius) >> 2; 196 | final int zMax = (z + radius) >> 2; 197 | final int xSize = xMax - xMin + 1; 198 | final int zSize = zMax - zMin + 1; 199 | // Generate biome's 200 | final BiomeBase[] biomes = getBiomes(null, xMin, zMin, xSize, zSize); 201 | // Make sure all biomes are allowed 202 | for (int i = 0; i < xSize * zSize; i++) { 203 | if (!allowedBiomes.contains(biomes[i])) { 204 | return false; 205 | } 206 | } 207 | return true; 208 | } 209 | 210 | /** 211 | * Returns random position within biome if it can be found in given area. 212 | * Otherwise null. Used for initial guess at spawn point and stronghold 213 | * locations. 214 | */ 215 | @Override 216 | public ChunkPosition a(final int x, final int z, final int radius, @SuppressWarnings("rawtypes") final List allowedBiomes, final Random random) { 217 | // Convert center and radius to minimum and size 218 | final int xMin = (x - radius) >> 2; 219 | final int zMin = (z - radius) >> 2; 220 | final int xMax = (x + radius) >> 2; 221 | final int zMax = (z + radius) >> 2; 222 | final int xSize = xMax - xMin + 1; 223 | final int zSize = zMax - zMin + 1; 224 | // Generate biome's 225 | final BiomeBase[] biomes = getBiomes(null, xMin, zMin, xSize, zSize); 226 | ChunkPosition result = null; 227 | int count = 0; 228 | for (int i = 0; i < xSize * zSize; i++) { 229 | final int xPosition = (xMin + (i % xSize)) << 2; 230 | final int zPosition = (zMin + (i / xSize)) << 2; 231 | if (allowedBiomes.contains(biomes[i]) && (result == null || random.nextInt(count + 1) == 0)) { 232 | result = new ChunkPosition(xPosition, 0, zPosition); 233 | count++; 234 | } 235 | } 236 | return result; 237 | } 238 | 239 | /** Cleans up biomeCache, called in tick */ 240 | @Override 241 | public void b() { 242 | // Clean up biomeCache 243 | biomeCache.a(); 244 | biomeGenerator.cleanupCache(); 245 | } 246 | } 247 | --------------------------------------------------------------------------------