mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-06-18 23:01:03 +00:00
Scattered ore (#424)
* Scattered Ore Impl * remove break * remove another break * sphereCount -> blockCount --------- Co-authored-by: Astrash <astrash@protonmail.com>
This commit is contained in:
@@ -19,8 +19,6 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
|
|
||||||
public class OreAddon implements AddonInitializer {
|
public class OreAddon implements AddonInitializer {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(OreAddon.class);
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Platform platform;
|
private Platform platform;
|
||||||
|
|
||||||
@@ -33,9 +31,7 @@ public class OreAddon implements AddonInitializer {
|
|||||||
.getHandler(FunctionalEventHandler.class)
|
.getHandler(FunctionalEventHandler.class)
|
||||||
.register(addon, ConfigPackPreLoadEvent.class)
|
.register(addon, ConfigPackPreLoadEvent.class)
|
||||||
.then(event -> event.getPack().registerConfigType(new OreConfigType(), addon.key("ORE"), 1))
|
.then(event -> event.getPack().registerConfigType(new OreConfigType(), addon.key("ORE"), 1))
|
||||||
|
.then(event -> event.getPack().registerConfigType(new ScatteredOreConfigType(), addon.key("SCATTERED_ORE"), 1))
|
||||||
.failThrough();
|
.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.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+37
@@ -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<ScatteredOreTemplate, Structure> {
|
||||||
|
public static final TypeKey<Structure> 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<ScatteredOreTemplate, Structure> getFactory() {
|
||||||
|
return factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeKey<Structure> getTypeKey() {
|
||||||
|
return ORE_TYPE_TOKEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
+27
@@ -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<ScatteredOreTemplate, Structure> {
|
||||||
|
@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());
|
||||||
|
}
|
||||||
|
}
|
||||||
+34
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
+20
-45
@@ -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.util.vector.Vector3Int;
|
||||||
import com.dfsek.terra.api.world.WritableWorld;
|
import com.dfsek.terra.api.world.WritableWorld;
|
||||||
|
|
||||||
|
import static com.dfsek.terra.addons.ore.utils.VanillaOreUtils.shouldPlace;
|
||||||
|
|
||||||
|
|
||||||
public class VanillaOre implements Structure {
|
public class VanillaOre implements Structure {
|
||||||
|
|
||||||
private final BlockState material;
|
protected final BlockState material;
|
||||||
|
|
||||||
private final double size;
|
protected final double size;
|
||||||
private final MaterialSet replaceable;
|
protected final MaterialSet replaceable;
|
||||||
private final boolean applyGravity;
|
protected final boolean applyGravity;
|
||||||
private final double exposed;
|
protected final double exposed;
|
||||||
private final Map<BlockType, BlockState> materials;
|
protected final Map<BlockType, BlockState> materials;
|
||||||
|
|
||||||
public VanillaOre(BlockState material, double size, MaterialSet replaceable, boolean applyGravity,
|
public VanillaOre(BlockState material, double size, MaterialSet replaceable, boolean applyGravity,
|
||||||
double exposed, Map<BlockType, BlockState> materials) {
|
double exposed, Map<BlockType, BlockState> materials) {
|
||||||
@@ -41,16 +43,6 @@ public class VanillaOre implements Structure {
|
|||||||
this.materials = materials;
|
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) {
|
public static double lerp(double t, double v0, double v1) {
|
||||||
return v0 + t * (v1 - v0);
|
return v0 + t * (v1 - v0);
|
||||||
}
|
}
|
||||||
@@ -58,14 +50,14 @@ public class VanillaOre implements Structure {
|
|||||||
@Override
|
@Override
|
||||||
public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) {
|
public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) {
|
||||||
float randomRadian = random.nextFloat() * (float) Math.PI;
|
float randomRadian = random.nextFloat() * (float) Math.PI;
|
||||||
double eigthSize = size / 8.0F;
|
double eighthSize = size / 8.0F;
|
||||||
|
|
||||||
// Place points to form a line segment
|
// Place points to form a line segment
|
||||||
double startX = (double) location.getX() + MathUtil.sin(randomRadian) * eigthSize;
|
double startX = (double) location.getX() + MathUtil.sin(randomRadian) * eighthSize;
|
||||||
double endX = (double) location.getX() - MathUtil.sin(randomRadian) * eigthSize;
|
double endX = (double) location.getX() - MathUtil.sin(randomRadian) * eighthSize;
|
||||||
|
|
||||||
double startZ = (double) location.getZ() + MathUtil.cos(randomRadian) * eigthSize;
|
double startZ = (double) location.getZ() + MathUtil.cos(randomRadian) * eighthSize;
|
||||||
double endZ = (double) location.getZ() - MathUtil.cos(randomRadian) * eigthSize;
|
double endZ = (double) location.getZ() - MathUtil.cos(randomRadian) * eighthSize;
|
||||||
|
|
||||||
double startY = location.getY() + random.nextInt(3) - 2;
|
double startY = location.getY() + random.nextInt(3) - 2;
|
||||||
double endY = 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 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 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 verticalSize = 2 * (2 + outset);
|
||||||
|
|
||||||
int sphereCount = 0;
|
int blockCount = 0;
|
||||||
BitSet visited = new BitSet(horizontalSize * verticalSize * horizontalSize);
|
BitSet visited = new BitSet(horizontalSize * verticalSize * horizontalSize);
|
||||||
|
|
||||||
// Generate a sphere at each point
|
// Generate a sphere at each point
|
||||||
@@ -159,10 +151,9 @@ public class VanillaOre implements Structure {
|
|||||||
|
|
||||||
visited.set(index);
|
visited.set(index);
|
||||||
BlockType block = world.getBlockState(xi, yi, zi).getBlockType();
|
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());
|
world.setBlockState(xi, yi, zi, getMaterial(block), isApplyGravity());
|
||||||
++sphereCount;
|
++blockCount;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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) {
|
public BlockState getMaterial(BlockType replace) {
|
||||||
return materials.getOrDefault(replace, material);
|
return materials.getOrDefault(replace, material);
|
||||||
}
|
}
|
||||||
|
|||||||
+56
@@ -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<BlockType, BlockState> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
+37
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user