diff --git a/src/main/java/com/dfsek/terra/config/TerraConfig.java b/src/main/java/com/dfsek/terra/config/TerraConfig.java index 7334c3e8a..545fba57f 100644 --- a/src/main/java/com/dfsek/terra/config/TerraConfig.java +++ b/src/main/java/com/dfsek/terra/config/TerraConfig.java @@ -1,24 +1,37 @@ package com.dfsek.terra.config; import com.dfsek.terra.config.base.ConfigPack; +import org.bukkit.Color; +import org.bukkit.Location; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.util.List; +import java.util.Map; +import java.util.Set; -public abstract class TerraConfig extends YamlConfiguration { +@SuppressWarnings("unused") +public abstract class TerraConfig { private final ConfigPack config; + private final YamlConfiguration yaml; public TerraConfig(File file, ConfigPack config) throws IOException, InvalidConfigurationException { - load(file); + yaml = new YamlConfiguration(); + yaml.load(file); this.config = config; } public TerraConfig(InputStream stream, ConfigPack config) throws IOException, InvalidConfigurationException { - load(new InputStreamReader(stream)); + yaml = new YamlConfiguration(); + yaml.load(new InputStreamReader(stream)); this.config = config; } @@ -27,4 +40,244 @@ public abstract class TerraConfig extends YamlConfiguration { } public abstract String getID(); + + + public @NotNull Set getKeys(boolean deep) { + return yaml.getKeys(deep); + } + + + public @NotNull Map getValues(boolean deep) { + return yaml.getValues(deep); + } + + + public boolean contains(@NotNull String path) { + return yaml.contains(path); + } + + + public boolean contains(@NotNull String path, boolean ignoreDefault) { + return yaml.contains(path, ignoreDefault); + } + + + public boolean isSet(@NotNull String path) { + return yaml.isSet(path); + } + + + public @Nullable Object get(@NotNull String path) { + return yaml.get(path); + } + + + public @Nullable Object get(@NotNull String path, @Nullable Object def) { + return yaml.get(path, def); + } + + + public @Nullable String getString(@NotNull String path) { + return yaml.getString(path); + } + + + public @Nullable String getString(@NotNull String path, @Nullable String def) { + return yaml.getString(path, def); + } + + + public boolean isString(@NotNull String path) { + return yaml.isString(path); + } + + + public int getInt(@NotNull String path) { + return yaml.getInt(path); + } + + + public int getInt(@NotNull String path, int def) { + return yaml.getInt(path, def); + } + + + public boolean isInt(@NotNull String path) { + return yaml.isInt(path); + } + + + public boolean getBoolean(@NotNull String path) { + return yaml.getBoolean(path); + } + + + public boolean getBoolean(@NotNull String path, boolean def) { + return yaml.getBoolean(path, def); + } + + + public boolean isBoolean(@NotNull String path) { + return yaml.isBoolean(path); + } + + + public double getDouble(@NotNull String path) { + return yaml.getDouble(path); + } + + + public double getDouble(@NotNull String path, double def) { + return yaml.getDouble(path, def); + } + + + public boolean isDouble(@NotNull String path) { + return yaml.isDouble(path); + } + + + public long getLong(@NotNull String path) { + return yaml.getLong(path); + } + + + public long getLong(@NotNull String path, long def) { + return yaml.getLong(path, def); + } + + + public boolean isLong(@NotNull String path) { + return yaml.isLong(path); + } + + + public @Nullable List getList(@NotNull String path) { + return yaml.getList(path); + } + + + public @Nullable List getList(@NotNull String path, @Nullable List def) { + return yaml.getList(path, def); + } + + + public boolean isList(@NotNull String path) { + return yaml.isList(path); + } + + + public @NotNull List getStringList(@NotNull String path) { + return yaml.getStringList(path); + } + + + public @NotNull List getIntegerList(@NotNull String path) { + return yaml.getIntegerList(path); + } + + + public @NotNull List getBooleanList(@NotNull String path) { + return yaml.getBooleanList(path); + } + + + public @NotNull List getDoubleList(@NotNull String path) { + return yaml.getDoubleList(path); + } + + + public @NotNull List getFloatList(@NotNull String path) { + return yaml.getFloatList(path); + } + + + public @NotNull List getLongList(@NotNull String path) { + return yaml.getLongList(path); + } + + + public @NotNull List getByteList(@NotNull String path) { + return yaml.getByteList(path); + } + + + public @NotNull List getCharacterList(@NotNull String path) { + return yaml.getCharacterList(path); + } + + + public @NotNull List getShortList(@NotNull String path) { + return yaml.getShortList(path); + } + + + public @NotNull List> getMapList(@NotNull String path) { + return yaml.getMapList(path); + } + + + public @Nullable T getObject(@NotNull String path, @NotNull Class clazz) { + return yaml.getObject(path, clazz); + } + + + public @Nullable T getObject(@NotNull String path, @NotNull Class clazz, @Nullable T def) { + return yaml.getObject(path, clazz, def); + } + + + public @Nullable T getSerializable(@NotNull String path, @NotNull Class clazz) { + return yaml.getSerializable(path, clazz); + } + + + public @Nullable T getSerializable(@NotNull String path, @NotNull Class clazz, @Nullable T def) { + return yaml.getSerializable(path, clazz, def); + } + + + public @Nullable ItemStack getItemStack(@NotNull String path) { + return yaml.getItemStack(path); + } + + + public @Nullable ItemStack getItemStack(@NotNull String path, @Nullable ItemStack def) { + return yaml.getItemStack(path, def); + } + + + public boolean isItemStack(@NotNull String path) { + return yaml.isItemStack(path); + } + + + public @Nullable Color getColor(@NotNull String path) { + return yaml.getColor(path); + } + + + public @Nullable Color getColor(@NotNull String path, @Nullable Color def) { + return yaml.getColor(path, def); + } + + + public boolean isColor(@NotNull String path) { + return yaml.isColor(path); + } + + + public @Nullable Location getLocation(@NotNull String path) { + return yaml.getLocation(path); + } + + + public @Nullable Location getLocation(@NotNull String path, @Nullable Location def) { + return yaml.getLocation(path, def); + } + + + public boolean isLocation(@NotNull String path) { + return yaml.isLocation(path); + } } diff --git a/src/main/java/com/dfsek/terra/config/base/ConfigPack.java b/src/main/java/com/dfsek/terra/config/base/ConfigPack.java index e76565dcb..7f99bfd72 100644 --- a/src/main/java/com/dfsek/terra/config/base/ConfigPack.java +++ b/src/main/java/com/dfsek/terra/config/base/ConfigPack.java @@ -40,7 +40,7 @@ import java.util.stream.Collectors; /** * Represents a Terra configuration pack. */ -public class ConfigPack extends YamlConfiguration { +public class ConfigPack { private static final Map configs = new HashMap<>(); public final List biomeList; public final double zoneFreq; @@ -61,8 +61,8 @@ public class ConfigPack extends YamlConfiguration { public final boolean vanillaDecoration; public final boolean vanillaMobs; public final boolean preventSaplingOverride; - public final Map locatable = new HashMap<>(); + private final YamlConfiguration yaml; private final Map ores; private final Map palettes; private final Map carvers; @@ -77,12 +77,14 @@ public class ConfigPack extends YamlConfiguration { private final String id; public ConfigPack(File file) throws IOException, InvalidConfigurationException { + yaml = new YamlConfiguration(); + yaml.load(new File(file, "pack.yml")); + long l = System.nanoTime(); - load(new File(file, "pack.yml")); dataFolder = file; - if(!contains("id")) throw new ConfigException("No ID specified!", "null"); - this.id = getString("id"); + if(!yaml.contains("id")) throw new ConfigException("No ID specified!", "null"); + this.id = yaml.getString("id"); ores = ConfigLoader.load(new File(file, "ores").toPath(), this, OreConfig.class); @@ -107,37 +109,37 @@ public class ConfigPack extends YamlConfiguration { grids = ConfigLoader.load(new File(file, "grids").toPath(), this, BiomeGridConfig.class); - zoneFreq = 1f / getInt("frequencies.zone", 1536); - freq1 = 1f / getInt("frequencies.grid-x", 256); - freq2 = 1f / getInt("frequencies.grid-z", 512); + zoneFreq = 1f / yaml.getInt("frequencies.zone", 1536); + freq1 = 1f / yaml.getInt("frequencies.grid-x", 256); + freq2 = 1f / yaml.getInt("frequencies.grid-z", 512); - biomeBlend = getBoolean("blend.enable", false); - blendAmp = getInt("blend.amplitude", 8); - blendFreq = getDouble("blend.frequency", 0.01); + biomeBlend = yaml.getBoolean("blend.enable", false); + blendAmp = yaml.getInt("blend.amplitude", 8); + blendFreq = yaml.getDouble("blend.frequency", 0.01); - erosionEnable = getBoolean("erode.enable", false); - erosionFreq = getDouble("erode.frequency", 0.01); - erosionThresh = getDouble("erode.threshold", 0.04); - erosionOctaves = getInt("erode.octaves", 3); + erosionEnable = yaml.getBoolean("erode.enable", false); + erosionFreq = yaml.getDouble("erode.frequency", 0.01); + erosionThresh = yaml.getDouble("erode.threshold", 0.04); + erosionOctaves = yaml.getInt("erode.octaves", 3); - octaves = getInt("noise.octaves", 4); - frequency = getDouble("noise.frequency", 1f / 96); + octaves = yaml.getInt("noise.octaves", 4); + frequency = yaml.getDouble("noise.frequency", 1f / 96); - erosionName = getString("erode.grid"); + erosionName = yaml.getString("erode.grid"); - vanillaCaves = getBoolean("vanilla.caves", false); - vanillaStructures = getBoolean("vanilla.structures", false); - vanillaDecoration = getBoolean("vanilla.decorations", false); - vanillaMobs = getBoolean("vanilla.mobs", false); + vanillaCaves = yaml.getBoolean("vanilla.caves", false); + vanillaStructures = yaml.getBoolean("vanilla.structures", false); + vanillaDecoration = yaml.getBoolean("vanilla.decorations", false); + vanillaMobs = yaml.getBoolean("vanilla.mobs", false); - preventSaplingOverride = getBoolean("prevent-sapling-override", false); + preventSaplingOverride = yaml.getBoolean("prevent-sapling-override", false); if(vanillaMobs || vanillaDecoration || vanillaStructures || vanillaCaves) { Terra.getInstance().getLogger().warning("WARNING: Vanilla features have been enabled! These features may not work properly, and are not officially supported! Use at your own risk!"); } // Load BiomeGrids from BiomeZone - biomeList = getStringList("grids"); + biomeList = yaml.getStringList("grids"); for(String biome : biomeList) { if(getBiomeGrid(biome) == null) { @@ -152,7 +154,7 @@ public class ConfigPack extends YamlConfiguration { allStructures.addAll(b.getStructures()); } - ConfigurationSection st = getConfigurationSection("locatable"); + ConfigurationSection st = yaml.getConfigurationSection("locatable"); if(st != null) { Map strucLocatable = st.getValues(false); for(Map.Entry e : strucLocatable.entrySet()) { @@ -169,6 +171,10 @@ public class ConfigPack extends YamlConfiguration { LangUtil.log("config-pack.loaded", Level.INFO, getID(), String.valueOf((System.nanoTime() - l) / 1000000D)); } + public BiomeGridConfig getBiomeGrid(String id) { + return grids.get(id); + } + public String getID() { return id; } @@ -181,10 +187,6 @@ public class ConfigPack extends YamlConfiguration { return structures.get(id); } - public BiomeGridConfig getBiomeGrid(String id) { - return grids.get(id); - } - public static synchronized void loadAll(JavaPlugin main) { configs.clear(); File file = new File(main.getDataFolder(), "packs"); diff --git a/src/main/java/com/dfsek/terra/config/genconfig/BiomeGridConfig.java b/src/main/java/com/dfsek/terra/config/genconfig/BiomeGridConfig.java index 1a8c8f749..a6f3fcdfc 100644 --- a/src/main/java/com/dfsek/terra/config/genconfig/BiomeGridConfig.java +++ b/src/main/java/com/dfsek/terra/config/genconfig/BiomeGridConfig.java @@ -24,7 +24,6 @@ public class BiomeGridConfig extends TerraConfig { @SuppressWarnings("unchecked") public BiomeGridConfig(File file, ConfigPack config) throws IOException, InvalidConfigurationException { super(file, config); - load(file); if(!contains("id")) throw new ConfigException("Grid ID unspecified!", "null"); this.gridID = getString("id"); if(!contains("grid")) throw new ConfigException("Grid key not found!", getID()); diff --git a/src/main/java/com/dfsek/terra/generation/entities/MultiChunkOre.java b/src/main/java/com/dfsek/terra/generation/entities/MultiChunkOre.java new file mode 100644 index 000000000..57503347c --- /dev/null +++ b/src/main/java/com/dfsek/terra/generation/entities/MultiChunkOre.java @@ -0,0 +1,63 @@ +package com.dfsek.terra.generation.entities; + +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.Vector; +import org.polydev.gaea.math.FastNoiseLite; +import org.polydev.gaea.population.ChunkCoordinate; + +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import java.util.Set; + +public class MultiChunkOre extends Ore { + protected final int min; + protected final int max; + + public MultiChunkOre(BlockData oreData, int min, int max, double deform, double deformFrequency, String id, + boolean update, int chunkEdgeOffset, Set replaceable) { + super(oreData, deform, deformFrequency, id, update, chunkEdgeOffset, replaceable); + this.min = min; + this.max = max; + } + + @Override + public void generate(Location location, Random random, JavaPlugin plugin) { + FastNoiseLite noise = new FastNoiseLite(random.nextInt()); + noise.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2); + noise.setFrequency(deformFrequency); + + Chunk chunk = location.getChunk(); + + int rad = randomInRange(random, min, max); + Map chunks = new HashMap<>(); // Cache chunks to prevent re-loading chunks every time one is needed. + chunks.put(new ChunkCoordinate(chunk), chunk); + for(int x = -rad; x <= rad; x++) { + for(int y = -rad; y <= rad; y++) { + for(int z = -rad; z <= rad; z++) { + Vector origin = location.toVector(); + Vector source = origin.clone().add(new Vector(x, y, z)); + + Vector orig = new Vector(location.getBlockX() + (chunk.getX() << 4), location.getBlockY(), location.getBlockZ() + (chunk.getZ() << 4)); + Vector oreLocation = orig.clone().add(new Vector(x, y, z)); + + if(oreLocation.getBlockY() > 255 || oreLocation.getBlockY() < 0) + continue; + if(source.distance(origin) < (rad + 0.5) * ((noise.getNoise(x, y, z) + 1) * deform)) { + ChunkCoordinate coord = new ChunkCoordinate(Math.floorDiv(oreLocation.getBlockX(), 16), Math.floorDiv(oreLocation.getBlockZ(), 16), chunk.getWorld().getUID()); + + Block block = chunks.computeIfAbsent(coord, k -> chunk.getWorld().getChunkAt(oreLocation.toLocation(chunk.getWorld()))) + .getBlock(Math.floorMod(source.getBlockX(), 16), source.getBlockY(), Math.floorMod(source.getBlockZ(), 16)); // Chunk caching conditional computation + if(replaceable.contains(block.getType()) && block.getLocation().getY() >= 0) + block.setBlockData(oreData, update); + } + } + } + } + } +} diff --git a/src/main/java/com/dfsek/terra/generation/entities/Ore.java b/src/main/java/com/dfsek/terra/generation/entities/Ore.java index fc59518a0..c538aab17 100644 --- a/src/main/java/com/dfsek/terra/generation/entities/Ore.java +++ b/src/main/java/com/dfsek/terra/generation/entities/Ore.java @@ -1,53 +1,36 @@ package com.dfsek.terra.generation.entities; -import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.util.Vector; -import org.polydev.gaea.math.FastNoiseLite; -import org.polydev.gaea.population.ChunkCoordinate; -import java.util.HashMap; -import java.util.Map; import java.util.Random; import java.util.Set; -public class Ore implements GenerationEntity { - private final BlockData oreData; - private final int min; - private final int max; - private final double deform; - private final double deformFrequency; - private final String id; - private final boolean update; - private final boolean crossChunks; - private final int chunkEdgeOffset; - Set replaceable; +public abstract class Ore implements GenerationEntity { + protected final BlockData oreData; + protected final double deform; + protected final double deformFrequency; + protected final String id; + protected final boolean update; + protected final int chunkEdgeOffset; + protected final Set replaceable; - public Ore(BlockData oreData, int min, int max, double deform, double deformFrequency, String id, boolean update, boolean crossChunks, + public Ore(BlockData oreData, double deform, double deformFrequency, String id, boolean update, int chunkEdgeOffset, Set replaceable) { this.oreData = oreData; - this.min = min; - this.max = max; this.deform = deform; this.deformFrequency = deformFrequency; this.id = id; this.update = update; - this.crossChunks = crossChunks; this.chunkEdgeOffset = chunkEdgeOffset; this.replaceable = replaceable; } - @Override - public void generate(Location location, Random random, JavaPlugin plugin) { - if(crossChunks) - doVeinMulti(location, random); - else - doVeinSingle(location, random); - } +// @Override +// public abstract void generate(Location location, Random random, JavaPlugin plugin); @Override public boolean isValidLocation(Location location, JavaPlugin plugin) { @@ -55,64 +38,7 @@ public class Ore implements GenerationEntity { return (replaceable.contains(block.getType()) && (block.getLocation().getY() >= 0)); } - @SuppressWarnings("DuplicatedCode") - private void doVeinMulti(Location location, Random random) { - FastNoiseLite ore = new FastNoiseLite(random.nextInt()); - Chunk chunk = location.getChunk(); - - ore.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2); - ore.setFrequency(deformFrequency); - int rad = randomInRange(random); - Map chunks = new HashMap<>(); // Cache chunks to prevent re-loading chunks every time one is needed. - chunks.put(new ChunkCoordinate(chunk), chunk); - for(int x = -rad; x <= rad; x++) { - for(int y = -rad; y <= rad; y++) { - for(int z = -rad; z <= rad; z++) { - Vector origin = location.toVector(); - Vector source = origin.clone().add(new Vector(x, y, z)); - - Vector orig = new Vector(location.getBlockX() + (chunk.getX() << 4), location.getBlockY(), location.getBlockZ() + (chunk.getZ() << 4)); - Vector oreLocation = orig.clone().add(new Vector(x, y, z)); - - if(oreLocation.getBlockY() > 255 || oreLocation.getBlockY() < 0) continue; - if(source.distance(origin) < (rad + 0.5) * ((ore.getNoise(x, y, z) + 1) * deform)) { - ChunkCoordinate coord = new ChunkCoordinate(Math.floorDiv(oreLocation.getBlockX(), 16), Math.floorDiv(oreLocation.getBlockZ(), 16), chunk.getWorld().getUID()); - - Block block = chunks.computeIfAbsent(coord, k -> chunk.getWorld().getChunkAt(oreLocation.toLocation(chunk.getWorld()))) - .getBlock(Math.floorMod(source.getBlockX(), 16), source.getBlockY(), Math.floorMod(source.getBlockZ(), 16)); // Chunk caching conditional computation - if(replaceable.contains(block.getType()) && block.getLocation().getY() >= 0) - block.setBlockData(oreData, update); - } - } - } - } - } - - @SuppressWarnings("DuplicatedCode") - private void doVeinSingle(Location location, Random random) { - FastNoiseLite ore = new FastNoiseLite(random.nextInt()); - Chunk chunk = location.getChunk(); - - ore.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2); - ore.setFrequency(deformFrequency); - int rad = randomInRange(random); - for(int x = -rad; x <= rad; x++) { - for(int y = -rad; y <= rad; y++) { - for(int z = -rad; z <= rad; z++) { - Vector oreLoc = location.toVector().clone().add(new Vector(x, y, z)); - if(oreLoc.getBlockX() > 15 || oreLoc.getBlockZ() > 15 || oreLoc.getBlockY() > 255 || oreLoc.getBlockX() < 0 || oreLoc.getBlockZ() < 0 || oreLoc.getBlockY() < 0) - continue; - if(oreLoc.distance(location.toVector()) < (rad + 0.5) * ((ore.getNoise(x, y, z) + 1) * deform)) { - Block b = chunk.getBlock(oreLoc.getBlockX(), oreLoc.getBlockY(), oreLoc.getBlockZ()); - if(replaceable.contains(b.getType()) && b.getLocation().getY() >= 0) - b.setBlockData(oreData, update); - } - } - } - } - } - - private int randomInRange(Random r) { + protected int randomInRange(Random r, int min, int max) { return r.nextInt(max - min + 1) + min; } } diff --git a/src/main/java/com/dfsek/terra/generation/entities/SingleChunkOre.java b/src/main/java/com/dfsek/terra/generation/entities/SingleChunkOre.java new file mode 100644 index 000000000..c11e3b9dc --- /dev/null +++ b/src/main/java/com/dfsek/terra/generation/entities/SingleChunkOre.java @@ -0,0 +1,50 @@ +package com.dfsek.terra.generation.entities; + +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.Vector; +import org.polydev.gaea.math.FastNoiseLite; + +import java.util.Random; +import java.util.Set; + +public class SingleChunkOre extends Ore { + protected final int min; + protected final int max; + + public SingleChunkOre(BlockData oreData, int min, int max, double deform, double deformFrequency, String id, + boolean update, int chunkEdgeOffset, Set replaceable) { + super(oreData, deform, deformFrequency, id, update, chunkEdgeOffset, replaceable); + this.min = min; + this.max = max; + } + + @Override + public void generate(Location location, Random random, JavaPlugin plugin) { + FastNoiseLite noise = new FastNoiseLite(random.nextInt()); + noise.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2); + noise.setFrequency(deformFrequency); + + Chunk chunk = location.getChunk(); + + int rad = randomInRange(random, min, max); + for(int x = -rad; x <= rad; x++) { + for(int y = -rad; y <= rad; y++) { + for(int z = -rad; z <= rad; z++) { + Vector oreLoc = location.toVector().clone().add(new Vector(x, y, z)); + if(oreLoc.getBlockX() > 15 || oreLoc.getBlockZ() > 15 || oreLoc.getBlockY() > 255 || oreLoc.getBlockX() < 0 || oreLoc.getBlockZ() < 0 || oreLoc.getBlockY() < 0) + continue; + if(oreLoc.distance(location.toVector()) < (rad + 0.5) * ((noise.getNoise(x, y, z) + 1) * deform)) { + Block b = chunk.getBlock(oreLoc.getBlockX(), oreLoc.getBlockY(), oreLoc.getBlockZ()); + if(replaceable.contains(b.getType()) && b.getLocation().getY() >= 0) + b.setBlockData(oreData, update); + } + } + } + } + } +} diff --git a/src/main/java/com/dfsek/terra/generation/entities/VanillaOre.java b/src/main/java/com/dfsek/terra/generation/entities/VanillaOre.java new file mode 100644 index 000000000..e67e349c0 --- /dev/null +++ b/src/main/java/com/dfsek/terra/generation/entities/VanillaOre.java @@ -0,0 +1,85 @@ +package com.dfsek.terra.generation.entities; + +import net.royawesome.jlibnoise.MathHelper; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.Random; +import java.util.Set; + +public class VanillaOre extends Ore { + private final int size; + + public VanillaOre(BlockData oreData, int size, double deform, double deformFrequency, String id, + boolean update, + int chunkEdgeOffset, Set replaceable) { + super(oreData, deform, deformFrequency, id, update, chunkEdgeOffset, replaceable); + this.size = size; + } + + /** + * TODO: what the fuck does half of this do? + * + * @param location + * @param random + * @param plugin + */ + @Override + public void generate(Location location, Random random, JavaPlugin plugin) { + Chunk chunk = location.getChunk(); + + int centerX = location.getBlockX(); + int centerZ = location.getBlockZ(); + int centerY = location.getBlockY(); + + + float f = random.nextFloat() * (float) Math.PI; + + double d1 = centerX + 8 + MathHelper.sin(f) * size / 8.0F; + double d2 = centerX + 8 - MathHelper.sin(f) * size / 8.0F; + double d3 = centerZ + 8 + MathHelper.cos(f) * size / 8.0F; + double d4 = centerZ + 8 - MathHelper.cos(f) * size / 8.0F; + + double d5 = centerY + random.nextInt(3) - 2; + double d6 = centerY + random.nextInt(3) - 2; + + for(int i = 0; i < size; i++) { + float iFactor = (float) i / (float) size; + + double d10 = random.nextDouble() * size / 16.0D; + double d11 = (MathHelper.sin((float) Math.PI * iFactor) + 1.0) * d10 + 1.0; + double d12 = (MathHelper.sin((float) Math.PI * iFactor) + 1.0) * d10 + 1.0; + + int xStart = MathHelper.floor(d1 + (d2 - d1) * iFactor - d11 / 2.0D); + int yStart = MathHelper.floor(d5 + (d6 - d5) * iFactor - d12 / 2.0D); + int zStart = MathHelper.floor(d3 + (d4 - d3) * iFactor - d11 / 2.0D); + + int xEnd = MathHelper.floor(d1 + (d2 - d1) * iFactor + d11 / 2.0D); + int yEnd = MathHelper.floor(d5 + (d6 - d5) * iFactor + d12 / 2.0D); + int zEnd = MathHelper.floor(d3 + (d4 - d3) * iFactor + d11 / 2.0D); + + for(int x = xStart; x <= xEnd; x++) { + double d13 = (x + 0.5D - (d1 + (d2 - d1) * iFactor)) / (d11 / 2.0D); + + if(d13 * d13 < 1.0D) { + for(int y = yStart; y <= yEnd; y++) { + double d14 = (y + 0.5D - (d5 + (d6 - d5) * iFactor)) / (d12 / 2.0D); + if(d13 * d13 + d14 * d14 < 1.0D) { + for(int z = zStart; z <= zEnd; z++) { + double d15 = (z + 0.5D - (d3 + (d4 - d3) * iFactor)) / (d11 / 2.0D); + Block block = chunk.getBlock(x, y, z); + if((d13 * d13 + d14 * d14 + d15 * d15 < 1.0D) && replaceable.contains(block.getType())) { + block.setBlockData(oreData, update); + } + } + } + } + } + } + } + } +}