diff --git a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/OreAddon.java b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/OreAddon.java index ff2ddf54c..2765391b4 100644 --- a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/OreAddon.java +++ b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/OreAddon.java @@ -19,8 +19,6 @@ import org.slf4j.LoggerFactory; public class OreAddon implements AddonInitializer { - private static final Logger logger = LoggerFactory.getLogger(OreAddon.class); - @Inject private Platform platform; @@ -33,9 +31,7 @@ public class OreAddon implements AddonInitializer { .getHandler(FunctionalEventHandler.class) .register(addon, ConfigPackPreLoadEvent.class) .then(event -> event.getPack().registerConfigType(new OreConfigType(), addon.key("ORE"), 1)) + .then(event -> event.getPack().registerConfigType(new ScatteredOreConfigType(), addon.key("SCATTERED_ORE"), 1)) .failThrough(); - - if(platform.getTerraConfig().isDebugLog()) - logger.warn("The ore-config addon is deprecated and scheduled for removal in Terra 7.0. It is recommended to use the ore-config-v2 addon for future pack development instead."); } } diff --git a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ScatteredOreConfigType.java b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ScatteredOreConfigType.java new file mode 100644 index 000000000..e777c09b9 --- /dev/null +++ b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ScatteredOreConfigType.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020-2021 Polyhedral Development + * + * The Terra Core Addons are licensed under the terms of the MIT License. For more details, + * reference the LICENSE file in this module's root directory. + */ + +package com.dfsek.terra.addons.ore; + +import com.dfsek.terra.api.Platform; +import com.dfsek.terra.api.config.ConfigFactory; +import com.dfsek.terra.api.config.ConfigPack; +import com.dfsek.terra.api.config.ConfigType; +import com.dfsek.terra.api.structure.Structure; +import com.dfsek.terra.api.util.reflection.TypeKey; + + +public class ScatteredOreConfigType implements ConfigType { + public static final TypeKey ORE_TYPE_TOKEN = new TypeKey<>() { + }; + private final ScatteredOreFactory factory = new ScatteredOreFactory(); + + @Override + public ScatteredOreTemplate getTemplate(ConfigPack pack, Platform platform) { + return new ScatteredOreTemplate(); + } + + @Override + public ConfigFactory getFactory() { + return factory; + } + + @Override + public TypeKey getTypeKey() { + return ORE_TYPE_TOKEN; + } +} diff --git a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ScatteredOreFactory.java b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ScatteredOreFactory.java new file mode 100644 index 000000000..171c85127 --- /dev/null +++ b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ScatteredOreFactory.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020-2021 Polyhedral Development + * + * The Terra Core Addons are licensed under the terms of the MIT License. For more details, + * reference the LICENSE file in this module's root directory. + */ + +package com.dfsek.terra.addons.ore; + +import com.dfsek.tectonic.api.exception.LoadException; + +import com.dfsek.terra.addons.ore.ores.VanillaOre; +import com.dfsek.terra.addons.ore.ores.VanillaScatteredOre; +import com.dfsek.terra.api.Platform; +import com.dfsek.terra.api.block.state.BlockState; +import com.dfsek.terra.api.config.ConfigFactory; +import com.dfsek.terra.api.structure.Structure; + + +public class ScatteredOreFactory implements ConfigFactory { + @Override + public Structure build(ScatteredOreTemplate config, Platform platform) throws LoadException { + BlockState m = config.getMaterial(); + return new VanillaScatteredOre(m, config.getSize(), config.getReplaceable(), config.doPhysics(), config.isExposed(), + config.getMaterialOverrides(), config.getSpread()); + } +} diff --git a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ScatteredOreTemplate.java b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ScatteredOreTemplate.java new file mode 100644 index 000000000..9c98552a5 --- /dev/null +++ b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ScatteredOreTemplate.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020-2021 Polyhedral Development + * + * The Terra Core Addons are licensed under the terms of the MIT License. For more details, + * reference the LICENSE file in this module's root directory. + */ + +package com.dfsek.terra.addons.ore; + +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Description; +import com.dfsek.tectonic.api.config.template.annotations.Final; +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import com.dfsek.terra.api.block.BlockType; +import com.dfsek.terra.api.block.state.BlockState; +import com.dfsek.terra.api.config.AbstractableTemplate; +import com.dfsek.terra.api.config.meta.Meta; +import com.dfsek.terra.api.util.collection.MaterialSet; + +import java.util.HashMap; +import java.util.Map; + + +@SuppressWarnings({ "unused", "FieldMayBeFinal" }) +public class ScatteredOreTemplate extends OreTemplate { + @Value("size") + private @Meta int spread = 7; + + + public int getSpread() { + return spread; + } +} diff --git a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ores/VanillaOre.java b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ores/VanillaOre.java index 0e09ffcb7..05a9e4a92 100644 --- a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ores/VanillaOre.java +++ b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ores/VanillaOre.java @@ -20,16 +20,18 @@ import com.dfsek.terra.api.util.collection.MaterialSet; import com.dfsek.terra.api.util.vector.Vector3Int; import com.dfsek.terra.api.world.WritableWorld; +import static com.dfsek.terra.addons.ore.utils.VanillaOreUtils.shouldPlace; + public class VanillaOre implements Structure { - private final BlockState material; + protected final BlockState material; - private final double size; - private final MaterialSet replaceable; - private final boolean applyGravity; - private final double exposed; - private final Map materials; + protected final double size; + protected final MaterialSet replaceable; + protected final boolean applyGravity; + protected final double exposed; + protected final Map materials; public VanillaOre(BlockState material, double size, MaterialSet replaceable, boolean applyGravity, double exposed, Map materials) { @@ -41,16 +43,6 @@ public class VanillaOre implements Structure { this.materials = materials; } - protected static boolean shouldNotDiscard(Random random, double chance) { - if(chance <= 0.0F) { - return true; - } else if(chance >= 1.0F) { - return false; - } else { - return random.nextFloat() >= chance; - } - } - public static double lerp(double t, double v0, double v1) { return v0 + t * (v1 - v0); } @@ -58,14 +50,14 @@ public class VanillaOre implements Structure { @Override public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) { float randomRadian = random.nextFloat() * (float) Math.PI; - double eigthSize = size / 8.0F; + double eighthSize = size / 8.0F; // Place points to form a line segment - double startX = (double) location.getX() + MathUtil.sin(randomRadian) * eigthSize; - double endX = (double) location.getX() - MathUtil.sin(randomRadian) * eigthSize; + double startX = (double) location.getX() + MathUtil.sin(randomRadian) * eighthSize; + double endX = (double) location.getX() - MathUtil.sin(randomRadian) * eighthSize; - double startZ = (double) location.getZ() + MathUtil.cos(randomRadian) * eigthSize; - double endZ = (double) location.getZ() - MathUtil.cos(randomRadian) * eigthSize; + double startZ = (double) location.getZ() + MathUtil.cos(randomRadian) * eighthSize; + double endZ = (double) location.getZ() - MathUtil.cos(randomRadian) * eighthSize; double startY = location.getY() + random.nextInt(3) - 2; double endY = location.getY() + random.nextInt(3) - 2; @@ -115,14 +107,14 @@ public class VanillaOre implements Structure { } int outset = (int) Math.ceil((size / 16.0F * 2.0F + 1.0F) / 2.0F); - int x = (int) (location.getX() - Math.ceil(eigthSize) - outset); + int x = (int) (location.getX() - Math.ceil(eighthSize) - outset); int y = location.getY() - 2 - outset; - int z = (int) (location.getZ() - Math.ceil(eigthSize) - outset); + int z = (int) (location.getZ() - Math.ceil(eighthSize) - outset); - int horizontalSize = (int) (2 * (Math.ceil(eigthSize) + outset)); + int horizontalSize = (int) (2 * (Math.ceil(eighthSize) + outset)); int verticalSize = 2 * (2 + outset); - int sphereCount = 0; + int blockCount = 0; BitSet visited = new BitSet(horizontalSize * verticalSize * horizontalSize); // Generate a sphere at each point @@ -159,10 +151,9 @@ public class VanillaOre implements Structure { visited.set(index); BlockType block = world.getBlockState(xi, yi, zi).getBlockType(); - if(shouldPlace(block, random, world, xi, yi, zi)) { + if(shouldPlace(getReplaceable(), block, exposed, random, world, xi, yi, zi)) { world.setBlockState(xi, yi, zi, getMaterial(block), isApplyGravity()); - ++sphereCount; - break; + ++blockCount; } } } @@ -174,24 +165,8 @@ public class VanillaOre implements Structure { } } - return sphereCount > 0; + return blockCount > 0; } - - public boolean shouldPlace(BlockType type, Random random, WritableWorld world, int x, int y, int z) { - if(!getReplaceable().contains(type)) { - return false; - } else if(shouldNotDiscard(random, exposed)) { - return true; - } else { - return !(world.getBlockState(x, y, z - 1).isAir() || - world.getBlockState(x, y, z + 1).isAir() || - world.getBlockState(x, y - 1, z).isAir() || - world.getBlockState(x, y + 1, z).isAir() || - world.getBlockState(x - 1, y, z).isAir() || - world.getBlockState(x + 1, y, z).isAir()); - } - } - public BlockState getMaterial(BlockType replace) { return materials.getOrDefault(replace, material); } diff --git a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ores/VanillaScatteredOre.java b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ores/VanillaScatteredOre.java new file mode 100644 index 000000000..fb30cff76 --- /dev/null +++ b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ores/VanillaScatteredOre.java @@ -0,0 +1,56 @@ +package com.dfsek.terra.addons.ore.ores; + +import com.dfsek.terra.addons.ore.utils.VanillaOreUtils; +import com.dfsek.terra.api.block.BlockType; +import com.dfsek.terra.api.block.state.BlockState; +import com.dfsek.terra.api.structure.Structure; +import com.dfsek.terra.api.util.Rotation; +import com.dfsek.terra.api.util.collection.MaterialSet; +import com.dfsek.terra.api.util.vector.Vector3; +import com.dfsek.terra.api.util.vector.Vector3Int; +import com.dfsek.terra.api.world.WritableWorld; + +import java.util.Map; +import java.util.Random; + +import static com.dfsek.terra.addons.ore.utils.VanillaOreUtils.shouldPlace; + + +public class VanillaScatteredOre extends VanillaOre { + protected final int spread; + public VanillaScatteredOre(BlockState material, double size, MaterialSet replaceable, boolean applyGravity, double exposed, + Map materials, int spread) { + super(material, size, replaceable, applyGravity, exposed, materials); + + this.spread = spread; + } + + @Override + public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) { + int i = random.nextInt((int) (size + 1)); + Vector3Int.Mutable mutable = Vector3Int.zero().mutable(); + + for(int j = 0; j < i; ++j) { + this.setPos(mutable, random, location, Math.min(j, spread)); + BlockType block = world.getBlockState(mutable).getBlockType(); + if (shouldPlace(getReplaceable(), block, exposed, random, world, mutable.getX(), mutable.getY(), mutable.getZ())) { + world.setBlockState(mutable, getMaterial(block), isApplyGravity()); + } + } + + return true; + } + + private void setPos(Vector3Int.Mutable mutable, Random random, Vector3Int location, int spread) { + int x = this.getSpread(random, spread); + int y = this.getSpread(random, spread); + int z = this.getSpread(random, spread); + mutable.setX(location.getX() + x); + mutable.setY(location.getY() + y); + mutable.setZ(location.getZ() + z); + } + + private int getSpread(Random random, int spread) { + return Math.round((random.nextFloat() - random.nextFloat()) * (float)spread); + } +} diff --git a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/utils/VanillaOreUtils.java b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/utils/VanillaOreUtils.java new file mode 100644 index 000000000..c03ce3752 --- /dev/null +++ b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/utils/VanillaOreUtils.java @@ -0,0 +1,37 @@ +package com.dfsek.terra.addons.ore.utils; + +import com.dfsek.terra.api.block.BlockType; +import com.dfsek.terra.api.util.collection.MaterialSet; +import com.dfsek.terra.api.world.WritableWorld; + +import java.util.Random; + + +public class VanillaOreUtils { + protected static boolean shouldNotDiscard(Random random, double chance) { + if(chance <= 0.0F) { + return true; + } else if(chance >= 1.0F) { + return false; + } else { + return random.nextFloat() >= chance; + } + } + + public static boolean shouldPlace(MaterialSet replaceable, BlockType type, Double exposed, Random random, WritableWorld world, int x, int y, int z) { + if(!replaceable.contains(type)) { + return false; + } else if(shouldNotDiscard(random, exposed)) { + return true; + } else { + return !(world.getBlockState(x, y, z - 1).isAir() || + world.getBlockState(x, y, z + 1).isAir() || + world.getBlockState(x, y - 1, z).isAir() || + world.getBlockState(x, y + 1, z).isAir() || + world.getBlockState(x - 1, y, z).isAir() || + world.getBlockState(x + 1, y, z).isAir()); + } + } + +} +