Initial release

This commit is contained in:
2022-10-27 10:28:51 +02:00
commit e7f9022dfb
55 changed files with 3781 additions and 0 deletions

View File

@@ -0,0 +1,183 @@
package de.nicolasklier.custom_structures.structures;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import de.nicolasklier.custom_structures.CustomStructures;
import de.nicolasklier.custom_structures.events.PlayerTick;
import de.nicolasklier.custom_structures.utils.PerlinNoise;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.Material;
import net.minecraft.client.MinecraftClient;
import net.minecraft.state.property.Properties;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Direction.Axis;
public class Generations {
List<Block> fence_whitelist = new ArrayList<>();
public Generations() {
fence_whitelist.add(Blocks.OAK_FENCE);
fence_whitelist.add(Blocks.BIRCH_FENCE);
fence_whitelist.add(Blocks.SPRUCE_FENCE);
fence_whitelist.add(Blocks.JUNGLE_FENCE);
}
public void spawnStaircase(BlockPos at, StaircaseOptions options) {
Map<BlockPos, BlockState> placeQueue = new HashMap<>();
MinecraftClient instance = MinecraftClient.getInstance();
int length = options.height * options.stretch * (options.mirror ? 2 : 1);
Random rng = new Random();
PerlinNoise noise = null;
int y = -(options.weight);
int step = 0;
if (options.noise != null) {
noise = new PerlinNoise(rng, options.noise.roughness, length, length);
noise.initialise();
}
// Final length is height times stretch factor. If mirroring is enabled, then it will be twice as long.
int x = 0;
boolean isMirroring = y > options.height * options.stretch;
if (step >= options.stretch) {
step = 0;
// Check if we already reached our final height. If yes, go downwards
if (isMirroring) {
y -= 1;
} else {
y++;
}
}
for (int z = 0; z < options.width; z++) {
boolean isNextHeight = true;
if (options.stretch > 1) {
if (isMirroring) {
isNextHeight = step == 0;
} else {
isNextHeight = step + 1 == options.stretch;
}
}
Block block = Blocks.COBBLESTONE;
// Build supporting fence
if (x % options.fenceVerticalDensity == 0 && y > 0) {
// From left to right
for (int z2 = 0; z2 <= options.width; z2 += (options.width - 1) / options.fenceHorizontalDensity) {
// Place fence manually on ground because the loop below offsets by one.
placeQueue.put(at.add(x + 1, 0, z2), getRandomFance(rng));
int y2 = y - options.weight;
while (true) {
Material mat = instance.getServer().getOverworld().getBlockState(new BlockPos(x, y2, z2)).getMaterial();
if (mat == Material.AIR || mat == Material.WATER) {
placeQueue.put(at.add(x, y2, z2), getRandomFance(rng));
placeQueue.put(at.add(x + 1, y2 + 1, z2), getRandomFance(rng));
} else {
break;
}
y2--;
}
}
}
boolean putStair = false;
// Decide if there should be mossy cobblestone or glass. If yes, then don't put a stair there.
if (rng.nextFloat() < options.chanceMossyCobblestone / 100f) {
block = Blocks.MOSSY_COBBLESTONE;
} else if (rng.nextFloat() < options.chanceGlass / 100f) {
block = Blocks.GLASS;
} else {
putStair = true;
}
// Build actual block
for (int j = 0; j < options.weight; j++) {
// Building imperfection
if (rng.nextFloat() < 0.001) continue;
placeQueue.put(at.add(x, y + j, z), block.getDefaultState());
}
Direction facing = isMirroring ? Direction.WEST : Direction.EAST;
// Build stair or not
if (putStair && isNextHeight) {
BlockState stairState = Blocks.COBBLESTONE_STAIRS.getDefaultState().with(Properties.HORIZONTAL_FACING, facing);
if (isMirroring)
stairState = stairState.with(Properties.HORIZONTAL_FACING, facing);
if (rng.nextFloat() < options.chanceSlap / 100f) {
placeQueue.put(at.add(x, y + options.weight, z), Blocks.SMOOTH_STONE_SLAB.getDefaultState());
} else {
CustomStructures.LOGGER.info("Noise [" + x + ", " + y + "]: " + noise.getValueAt(x, y + options.weight));
if (noise.getValueAt(x, y + options.weight) < options.chanceWoodStair / 100f) {
// Override stair as wood stair, copying the facing.
stairState = Blocks.OAK_STAIRS.getDefaultState()
.with(Properties.HORIZONTAL_FACING, stairState.get(Properties.HORIZONTAL_FACING));
} else if (rng.nextFloat() > options.chanceMossyCobblestone / 100f) {
stairState = Blocks.MOSSY_COBBLESTONE_STAIRS.getDefaultState()
.with(Properties.HORIZONTAL_FACING, stairState.get(Properties.HORIZONTAL_FACING));
}
placeQueue.put(at.add(x, y + options.weight, z), stairState);
}
} else {
if (rng.nextFloat() < 0.04) {
placeQueue.put(at.add(x, y + options.weight - 1, z), Blocks.GLOWSTONE.getDefaultState());
}
}
// Build wall
if ((z == 0 || z == options.width - 1) && options.wallHeight > 0) {
for (int y2 = 0; y2 < options.wallHeight; y2++) {
placeQueue.put(at.add(x, y + y2 + options.weight, z), Blocks.OAK_PLANKS.getDefaultState());
}
placeQueue.put(at.add(x, y + options.wallHeight + options.weight, z), Blocks.OAK_FENCE.getDefaultState());
placeQueue.put(at.add(x, y + options.wallHeight + options.weight + 1, z), Blocks.OAK_FENCE.getDefaultState());
placeQueue.put(at.add(x, y + options.wallHeight + options.weight + 2, z), Blocks.OAK_PLANKS.getDefaultState());
if (isNextHeight) {
placeQueue.put(at.add(x, y + options.wallHeight + options.weight + 3, z), Blocks.OAK_STAIRS.getDefaultState()
.with(Properties.HORIZONTAL_FACING, facing));
}
}
}
step++;
}
PlayerTick.queue.putAll(placeQueue);
Set<BlockPos> set = placeQueue.keySet();
List<BlockPos> list = new ArrayList<>(set);
//Collections.shuffle(list);
PlayerTick.queueKeys = list.iterator();
}
private BlockState getRandomFance(Random rng) {
return fence_whitelist.get(rng.nextInt(0, fence_whitelist.size() - 1)).getDefaultState();
}
}

View File

@@ -0,0 +1,11 @@
package de.nicolasklier.custom_structures.structures;
import java.util.Random;
public class StaircaseNoiseOptions {
public float roughness = 0.1f;
public Random rng = new Random();
}

View File

@@ -0,0 +1,74 @@
package de.nicolasklier.custom_structures.structures;
public class StaircaseOptions {
/**
* Width of the staircase on the Z-axis.
*/
public int width = 21;
/**
* Thickness of the staircase.
*/
public int weight = 3;
/**
* Height of the staircase on the Y-axis.
*/
public int height = 32;
/**
* Padding between the support fences vertically (XY-plane).
*/
public int fenceVerticalDensity = 10;
/**
* Padding between the support fences horizontally (ZY-plane).
*/
public int fenceHorizontalDensity = 3;
/**
* Height of the wall left & right. Set to 0 to disable this feature.
*/
public int wallHeight = 2;
/**
* Scratch the staircase along the X-axis.
*/
public int stretch = 4;
/**
* Mirror staircase when height is reached. This will double your length.
*/
public boolean mirror = false;
/**
* Value between 0% and 100% being the chance to spawn glass.
*/
public short chanceGlass = 10;
/**
* Value between 0% and 100% being the chance to spawn glowstone.
*/
public short chanceGlowstone = 4;
/**
* Value between 0% and 100% being the chance to spawn mossy cobblestone.
*/
public short chanceMossyCobblestone = 20;
/**
* Value between 0% and 100% being the chance to spawn a slap instead of an stair.
*/
public short chanceSlap = 5;
/**
* Value between 0% and 100% being the chance to spawn a wooden stair instead of an cobblestone stair.
*/
public short chanceWoodStair = 50;
/**
* Adds variation to the stretch of the staircase. This will override `stretch`.
* To disable this feature set it to null.
*/
public StaircaseNoiseOptions noise = null;
}