mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-04-03 06:16:10 +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 {
|
||||
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.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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,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<BlockType, BlockState> materials;
|
||||
protected final double size;
|
||||
protected final MaterialSet replaceable;
|
||||
protected final boolean applyGravity;
|
||||
protected final double exposed;
|
||||
protected final Map<BlockType, BlockState> materials;
|
||||
|
||||
public VanillaOre(BlockState material, double size, MaterialSet replaceable, boolean applyGravity,
|
||||
double exposed, Map<BlockType, BlockState> 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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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