Add perlin noise to staircase generation.
This commit is contained in:
@@ -16,6 +16,11 @@ repositories {
|
|||||||
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
|
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
|
||||||
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
|
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
|
||||||
// for more information about repositories.
|
// for more information about repositories.
|
||||||
|
|
||||||
|
maven {
|
||||||
|
name = "CottonMC"
|
||||||
|
url = "https://server.bbkr.space/artifactory/libs-release"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -31,6 +36,7 @@ dependencies {
|
|||||||
// These are included in the Fabric API production distribution and allow you to update your mod to the latest modules at a later more convenient time.
|
// These are included in the Fabric API production distribution and allow you to update your mod to the latest modules at a later more convenient time.
|
||||||
|
|
||||||
// modImplementation "net.fabricmc.fabric-api:fabric-api-deprecated:${project.fabric_version}"
|
// modImplementation "net.fabricmc.fabric-api:fabric-api-deprecated:${project.fabric_version}"
|
||||||
|
modImplementation include("io.github.cottonmc:LibGui:6.3.0+1.19")
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
package de.nicolasklier.custom_structures;
|
package de.nicolasklier.custom_structures;
|
||||||
|
|
||||||
import net.fabricmc.api.ModInitializer;
|
|
||||||
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
|
|
||||||
import net.minecraft.item.Item;
|
|
||||||
import net.minecraft.item.ItemGroup;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import net.minecraft.util.registry.Registry;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import de.nicolasklier.custom_structures.events.PlayerTick;
|
import de.nicolasklier.custom_structures.events.PlayerTick;
|
||||||
import de.nicolasklier.custom_structures.items.StructureSpawner;
|
import de.nicolasklier.custom_structures.items.StructureSpawner;
|
||||||
|
import net.fabricmc.api.ModInitializer;
|
||||||
|
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemGroup;
|
||||||
|
import net.minecraft.screen.ScreenHandlerType;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public class CustomStructures implements ModInitializer {
|
public class CustomStructures implements ModInitializer {
|
||||||
// This logger is used to write text to the console and the log file.
|
// This logger is used to write text to the console and the log file.
|
||||||
// It is considered best practice to use your mod id as the logger's name.
|
// It is considered best practice to use your mod id as the logger's name.
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import java.util.Iterator;
|
|||||||
|
|
||||||
import de.nicolasklier.custom_structures.CustomStructures;
|
import de.nicolasklier.custom_structures.CustomStructures;
|
||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.sound.SoundCategory;
|
import net.minecraft.sound.SoundCategory;
|
||||||
import net.minecraft.sound.SoundEvents;
|
import net.minecraft.sound.SoundEvents;
|
||||||
@@ -56,7 +57,7 @@ public class PlayerTick {
|
|||||||
|
|
||||||
//CustomStructures.LOGGER.info("Build at " + pos.toShortString() + "\t Q:" + queue.size());
|
//CustomStructures.LOGGER.info("Build at " + pos.toShortString() + "\t Q:" + queue.size());
|
||||||
|
|
||||||
instance.getServer().getOverworld().setBlockState(pos, state);
|
instance.getServer().getOverworld().setBlockState(pos, state, Block.NOTIFY_NEIGHBORS);
|
||||||
instance.world.addBlockBreakParticles(pos, state);
|
instance.world.addBlockBreakParticles(pos, state);
|
||||||
instance.world.playSound(pos, SoundEvents.BLOCK_STONE_PLACE, SoundCategory.BLOCKS, 1f, 1f, true);
|
instance.world.playSound(pos, SoundEvents.BLOCK_STONE_PLACE, SoundCategory.BLOCKS, 1f, 1f, true);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package de.nicolasklier.custom_structures.guis;
|
||||||
|
|
||||||
|
import io.github.cottonmc.cotton.gui.client.LightweightGuiDescription;
|
||||||
|
import io.github.cottonmc.cotton.gui.widget.WButton;
|
||||||
|
import io.github.cottonmc.cotton.gui.widget.WGridPanel;
|
||||||
|
import io.github.cottonmc.cotton.gui.widget.WLabel;
|
||||||
|
import io.github.cottonmc.cotton.gui.widget.WSlider;
|
||||||
|
import io.github.cottonmc.cotton.gui.widget.WSprite;
|
||||||
|
import io.github.cottonmc.cotton.gui.widget.data.Axis;
|
||||||
|
import io.github.cottonmc.cotton.gui.widget.data.Insets;
|
||||||
|
import net.minecraft.client.gui.hud.MessageIndicator.Icon;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public class SettingsGui extends LightweightGuiDescription {
|
||||||
|
|
||||||
|
public SettingsGui() {
|
||||||
|
WGridPanel root = new WGridPanel();
|
||||||
|
setRootPanel(root);
|
||||||
|
root.setSize(256, 240);
|
||||||
|
root.setInsets(Insets.ROOT_PANEL);
|
||||||
|
|
||||||
|
WLabel title = new WLabel(Text.of("Custom Structures"), 0x000000);
|
||||||
|
root.add(title, 0, 0, 2, 1);
|
||||||
|
|
||||||
|
//WSprite icon = new WSprite(new Identifier("minecraft:textures/item/redstone.png"));
|
||||||
|
//root.add(icon, 0, 2, 1, 1);
|
||||||
|
|
||||||
|
WLabel label_width = new WLabel(Text.of("Width"), 0x000000);
|
||||||
|
root.add(label_width , 0, 2, 2, 1);
|
||||||
|
|
||||||
|
WSlider slider = new WSlider(0, 100, Axis.HORIZONTAL);
|
||||||
|
root.add(slider, 0, 4, 5, 1);
|
||||||
|
|
||||||
|
WButton button = new WButton(Text.of("Save"));
|
||||||
|
root.add(button, 0, 10, 4, 1);
|
||||||
|
|
||||||
|
root.validate(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package de.nicolasklier.custom_structures.guis;
|
||||||
|
|
||||||
|
import io.github.cottonmc.cotton.gui.GuiDescription;
|
||||||
|
import io.github.cottonmc.cotton.gui.client.CottonClientScreen;
|
||||||
|
|
||||||
|
public class SettingsScreen extends CottonClientScreen {
|
||||||
|
|
||||||
|
public SettingsScreen(GuiDescription description) {
|
||||||
|
super(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package de.nicolasklier.custom_structures.items;
|
package de.nicolasklier.custom_structures.items;
|
||||||
|
|
||||||
import de.nicolasklier.custom_structures.Helper;
|
import de.nicolasklier.custom_structures.Helper;
|
||||||
|
import de.nicolasklier.custom_structures.guis.SettingsGui;
|
||||||
|
import de.nicolasklier.custom_structures.guis.SettingsScreen;
|
||||||
import de.nicolasklier.custom_structures.structures.Generations;
|
import de.nicolasklier.custom_structures.structures.Generations;
|
||||||
import de.nicolasklier.custom_structures.structures.StaircaseNoiseOptions;
|
import de.nicolasklier.custom_structures.structures.StaircaseNoiseOptions;
|
||||||
import de.nicolasklier.custom_structures.structures.StaircaseOptions;
|
import de.nicolasklier.custom_structures.structures.StaircaseOptions;
|
||||||
@@ -23,7 +25,15 @@ public class StructureSpawner extends Item {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
|
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
|
||||||
|
System.out.println("Used item!");
|
||||||
|
|
||||||
MinecraftClient client = MinecraftClient.getInstance();
|
MinecraftClient client = MinecraftClient.getInstance();
|
||||||
|
|
||||||
|
|
||||||
|
// If the player is sneaking, we open a setting menu.
|
||||||
|
if (client.player.isSneaking()) {
|
||||||
|
client.setScreen(new SettingsScreen(new SettingsGui()));
|
||||||
|
} else {
|
||||||
HitResult hit = Helper.raycastInDirection(client, client.getTickDelta(), client.cameraEntity.getRotationVec(client.getTickDelta()));
|
HitResult hit = Helper.raycastInDirection(client, client.getTickDelta(), client.cameraEntity.getRotationVec(client.getTickDelta()));
|
||||||
|
|
||||||
Generations gen = new Generations();
|
Generations gen = new Generations();
|
||||||
@@ -31,16 +41,19 @@ public class StructureSpawner extends Item {
|
|||||||
if (hit.getType() == Type.BLOCK) {
|
if (hit.getType() == Type.BLOCK) {
|
||||||
BlockHitResult result = (BlockHitResult) hit;
|
BlockHitResult result = (BlockHitResult) hit;
|
||||||
client.player.sendChatMessage("Coords: " + result.getBlockPos().toShortString(), null);
|
client.player.sendChatMessage("Coords: " + result.getBlockPos().toShortString(), null);
|
||||||
|
|
||||||
// Spawn structure at raycast hit
|
// Spawn structure at raycast hit
|
||||||
StaircaseOptions options = new StaircaseOptions();
|
StaircaseOptions options = new StaircaseOptions();
|
||||||
options.stretch = 2;
|
//options.stretch = 2;
|
||||||
options.height = 10;
|
options.width = 5;
|
||||||
|
options.height = 20;
|
||||||
options.noise = new StaircaseNoiseOptions();
|
options.noise = new StaircaseNoiseOptions();
|
||||||
|
options.noise.threshold = 0.64f;
|
||||||
|
options.minecartTrack = true;
|
||||||
options.mirror = true;
|
options.mirror = true;
|
||||||
|
|
||||||
gen.spawnStaircase(result.getBlockPos().add(0, 1, 0), options);
|
gen.spawnStaircase(result.getBlockPos().add(0, 1, 0), options);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return TypedActionResult.success(user.getStackInHand(hand));
|
return TypedActionResult.success(user.getStackInHand(hand));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
package de.nicolasklier.custom_structures.structures;
|
package de.nicolasklier.custom_structures.structures;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.spongepowered.noise.module.source.Perlin;
|
||||||
|
|
||||||
import de.nicolasklier.custom_structures.CustomStructures;
|
import de.nicolasklier.custom_structures.CustomStructures;
|
||||||
import de.nicolasklier.custom_structures.events.PlayerTick;
|
import de.nicolasklier.custom_structures.events.PlayerTick;
|
||||||
import de.nicolasklier.custom_structures.utils.PerlinNoise;
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
@@ -19,7 +19,6 @@ import net.minecraft.client.MinecraftClient;
|
|||||||
import net.minecraft.state.property.Properties;
|
import net.minecraft.state.property.Properties;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.util.math.Direction.Axis;
|
|
||||||
|
|
||||||
public class Generations {
|
public class Generations {
|
||||||
|
|
||||||
@@ -38,34 +37,85 @@ public class Generations {
|
|||||||
int length = options.height * options.stretch * (options.mirror ? 2 : 1);
|
int length = options.height * options.stretch * (options.mirror ? 2 : 1);
|
||||||
|
|
||||||
Random rng = new Random();
|
Random rng = new Random();
|
||||||
PerlinNoise noise = null;
|
Perlin noise = null;
|
||||||
|
|
||||||
|
int minecartTrackPosition = options.minecartTrack
|
||||||
|
&& options.width > 2
|
||||||
|
&& options.weight > 2
|
||||||
|
? options.width / 2
|
||||||
|
: 0;
|
||||||
|
int minecartRedstoneTorchStep = 0;
|
||||||
|
|
||||||
int y = -(options.weight);
|
int y = -(options.weight);
|
||||||
int step = 0;
|
int step = 0;
|
||||||
|
|
||||||
if (options.noise != null) {
|
if (options.noise != null) {
|
||||||
noise = new PerlinNoise(rng, options.noise.roughness, length, length);
|
noise = new Perlin();
|
||||||
noise.initialise();
|
noise.setSeed(rng.nextInt());
|
||||||
|
noise.setOctaveCount(3);
|
||||||
|
noise.setFrequency(0.3);
|
||||||
|
noise.setPersistence(0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final length is height times stretch factor. If mirroring is enabled, then it will be twice as long.
|
// Final length is height times stretch factor. If mirroring is enabled, then it will be twice as long.
|
||||||
int x = 0;
|
int x = 0;
|
||||||
boolean isMirroring = y > options.height * options.stretch;
|
|
||||||
|
|
||||||
|
boolean reachedTop = false;
|
||||||
|
|
||||||
|
// Very dangerous. But since we use noise to control the stretch of the staircase we cannot know how long it will be at the end.
|
||||||
|
while (true) {
|
||||||
|
x++;
|
||||||
|
|
||||||
|
boolean isMirroring = y > options.height && options.mirror || reachedTop;
|
||||||
|
|
||||||
|
if (isMirroring) {
|
||||||
|
reachedTop = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Break conditions
|
||||||
|
if (isMirroring && y <= -options.weight) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!options.mirror && y >= options.height) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (noise != null) {
|
||||||
|
// In 20% of all cases the y-level shouldn't change.
|
||||||
|
if (noise.get(x, 0, 0) < options.noise.threshold) {
|
||||||
|
if (isMirroring) y--;
|
||||||
|
else y++;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Noise: " + noise.get(x, 0, 0) + " | X: " + x + " Y: " + y);
|
||||||
|
} else {
|
||||||
if (step >= options.stretch) {
|
if (step >= options.stretch) {
|
||||||
step = 0;
|
step = 0;
|
||||||
|
|
||||||
// Check if we already reached our final height. If yes, go downwards
|
// Check if we already reached our final height. If yes, go downwards
|
||||||
if (isMirroring) {
|
if (isMirroring) {
|
||||||
y -= 1;
|
y--;
|
||||||
} else {
|
} else {
|
||||||
y++;
|
y++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int z = 0; z < options.width; z++) {
|
for (int z = 0; z < options.width; z++) {
|
||||||
boolean isNextHeight = true;
|
boolean isNextHeight = false;
|
||||||
|
|
||||||
|
if (noise != null) {
|
||||||
|
if (isMirroring) {
|
||||||
|
if (noise.get(x, 0, 0) < options.noise.threshold) {
|
||||||
|
isNextHeight = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (noise.get(x + 1, 0, 0) < options.noise.threshold) {
|
||||||
|
isNextHeight = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (options.stretch > 1) {
|
if (options.stretch > 1) {
|
||||||
if (isMirroring) {
|
if (isMirroring) {
|
||||||
isNextHeight = step == 0;
|
isNextHeight = step == 0;
|
||||||
@@ -73,18 +123,20 @@ public class Generations {
|
|||||||
isNextHeight = step + 1 == options.stretch;
|
isNextHeight = step + 1 == options.stretch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Block block = Blocks.COBBLESTONE;
|
Block block = Blocks.COBBLESTONE;
|
||||||
|
|
||||||
// Build supporting fence
|
// Build supporting fence
|
||||||
if (x % options.fenceVerticalDensity == 0 && y > 0) {
|
/*if (x % options.fenceVerticalDensity == 0 && y > 0) {
|
||||||
// From left to right
|
// From left to right
|
||||||
for (int z2 = 0; z2 <= options.width; z2 += (options.width - 1) / options.fenceHorizontalDensity) {
|
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.
|
// Place fence manually on ground because the loop below offsets by one.
|
||||||
placeQueue.put(at.add(x + 1, 0, z2), getRandomFance(rng));
|
placeQueue.put(at.add(x + 1, 0, z2), getRandomFance(rng));
|
||||||
|
|
||||||
int y2 = y - options.weight;
|
int y2 = y + 2;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
break;
|
||||||
Material mat = instance.getServer().getOverworld().getBlockState(new BlockPos(x, y2, z2)).getMaterial();
|
Material mat = instance.getServer().getOverworld().getBlockState(new BlockPos(x, y2, z2)).getMaterial();
|
||||||
if (mat == Material.AIR || mat == Material.WATER) {
|
if (mat == Material.AIR || mat == Material.WATER) {
|
||||||
placeQueue.put(at.add(x, y2, z2), getRandomFance(rng));
|
placeQueue.put(at.add(x, y2, z2), getRandomFance(rng));
|
||||||
@@ -93,18 +145,23 @@ public class Generations {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
System.out.println("Fence stuff " + y2 + "(" + mat.toString() + ")");
|
||||||
|
|
||||||
|
if (y2 <= -64)
|
||||||
|
break;
|
||||||
|
|
||||||
y2--;
|
y2--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
boolean putStair = false;
|
boolean putStair = false;
|
||||||
|
|
||||||
// Decide if there should be mossy cobblestone or glass. If yes, then don't put a stair there.
|
// Decide if there should be mossy cobblestone or cracked stone. If yes, then don't put a stair there.
|
||||||
if (rng.nextFloat() < options.chanceMossyCobblestone / 100f) {
|
if (rng.nextFloat() < options.chanceMossyCobblestone / 100f) {
|
||||||
block = Blocks.MOSSY_COBBLESTONE;
|
block = Blocks.MOSSY_COBBLESTONE;
|
||||||
} else if (rng.nextFloat() < options.chanceGlass / 100f) {
|
} else if (rng.nextFloat() < options.chanceStoneBricks / 100f) {
|
||||||
block = Blocks.GLASS;
|
block = Blocks.STONE_BRICKS;
|
||||||
} else {
|
} else {
|
||||||
putStair = true;
|
putStair = true;
|
||||||
}
|
}
|
||||||
@@ -129,8 +186,8 @@ public class Generations {
|
|||||||
if (rng.nextFloat() < options.chanceSlap / 100f) {
|
if (rng.nextFloat() < options.chanceSlap / 100f) {
|
||||||
placeQueue.put(at.add(x, y + options.weight, z), Blocks.SMOOTH_STONE_SLAB.getDefaultState());
|
placeQueue.put(at.add(x, y + options.weight, z), Blocks.SMOOTH_STONE_SLAB.getDefaultState());
|
||||||
} else {
|
} else {
|
||||||
CustomStructures.LOGGER.info("Noise [" + x + ", " + y + "]: " + noise.getValueAt(x, y + options.weight));
|
//CustomStructures.LOGGER.info("Noise [" + x + ", " + y + ", " + z + "]: " + noise.get(x, y + options.weight, z));
|
||||||
if (noise.getValueAt(x, y + options.weight) < options.chanceWoodStair / 100f) {
|
if (noise.get(x, y + options.weight, 0) < options.chanceWoodStair / 100f) {
|
||||||
|
|
||||||
// Override stair as wood stair, copying the facing.
|
// Override stair as wood stair, copying the facing.
|
||||||
stairState = Blocks.OAK_STAIRS.getDefaultState()
|
stairState = Blocks.OAK_STAIRS.getDefaultState()
|
||||||
@@ -163,6 +220,21 @@ public class Generations {
|
|||||||
.with(Properties.HORIZONTAL_FACING, facing));
|
.with(Properties.HORIZONTAL_FACING, facing));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Minecart rails
|
||||||
|
if (minecartTrackPosition > 0 && z == minecartTrackPosition) {
|
||||||
|
System.array
|
||||||
|
if (minecartRedstoneTorchStep >= 4) {
|
||||||
|
placeQueue.put(at.add(x, y + options.weight - 2, z), Blocks.REDSTONE_TORCH.getDefaultState());
|
||||||
|
placeQueue.put(at.add(x, y + options.weight, z), Blocks.POWERED_RAIL.getDefaultState());
|
||||||
|
|
||||||
|
minecartRedstoneTorchStep = 0;
|
||||||
|
} else {
|
||||||
|
placeQueue.put(at.add(x, y + options.weight, z), Blocks.RAIL.getDefaultState());
|
||||||
|
}
|
||||||
|
|
||||||
|
minecartRedstoneTorchStep++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
step++;
|
step++;
|
||||||
|
|||||||
@@ -6,6 +6,11 @@ public class StaircaseNoiseOptions {
|
|||||||
|
|
||||||
public float roughness = 0.1f;
|
public float roughness = 0.1f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Noise value that will change the y-level of the staircase.
|
||||||
|
*/
|
||||||
|
public float threshold = 0.7f;
|
||||||
|
|
||||||
public Random rng = new Random();
|
public Random rng = new Random();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,9 +42,9 @@ public class StaircaseOptions {
|
|||||||
public boolean mirror = false;
|
public boolean mirror = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Value between 0% and 100% being the chance to spawn glass.
|
* Value between 0% and 100% being the chance to spawn stone bricks.
|
||||||
*/
|
*/
|
||||||
public short chanceGlass = 10;
|
public short chanceStoneBricks = 10;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Value between 0% and 100% being the chance to spawn glowstone.
|
* Value between 0% and 100% being the chance to spawn glowstone.
|
||||||
@@ -71,4 +71,6 @@ public class StaircaseOptions {
|
|||||||
* To disable this feature set it to null.
|
* To disable this feature set it to null.
|
||||||
*/
|
*/
|
||||||
public StaircaseNoiseOptions noise = null;
|
public StaircaseNoiseOptions noise = null;
|
||||||
|
|
||||||
|
public boolean minecartTrack = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,110 +0,0 @@
|
|||||||
package de.nicolasklier.custom_structures.utils;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
public class PerlinNoise {
|
|
||||||
/** Source of entropy */
|
|
||||||
private Random rand_;
|
|
||||||
|
|
||||||
/** Amount of roughness */
|
|
||||||
float roughness_;
|
|
||||||
|
|
||||||
/** Plasma fractal grid */
|
|
||||||
private float[][] grid_;
|
|
||||||
|
|
||||||
|
|
||||||
/** Generate a noise source based upon the midpoint displacement fractal.
|
|
||||||
*
|
|
||||||
* @param rand The random number generator
|
|
||||||
* @param roughness a roughness parameter
|
|
||||||
* @param width the width of the grid
|
|
||||||
* @param height the height of the grid
|
|
||||||
*/
|
|
||||||
public PerlinNoise(Random rand, float roughness, int width, int height) {
|
|
||||||
roughness_ = roughness / width;
|
|
||||||
grid_ = new float[width][height];
|
|
||||||
rand_ = (rand == null) ? new Random() : rand;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void initialise() {
|
|
||||||
int xh = grid_.length - 1;
|
|
||||||
int yh = grid_[0].length - 1;
|
|
||||||
|
|
||||||
// set the corner points
|
|
||||||
grid_[0][0] = rand_.nextFloat() - 0.5f;
|
|
||||||
grid_[0][yh] = rand_.nextFloat() - 0.5f;
|
|
||||||
grid_[xh][0] = rand_.nextFloat() - 0.5f;
|
|
||||||
grid_[xh][yh] = rand_.nextFloat() - 0.5f;
|
|
||||||
|
|
||||||
// generate the fractal
|
|
||||||
generate(0, 0, xh, yh);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Add a suitable amount of random displacement to a point
|
|
||||||
private float roughen(float v, int l, int h) {
|
|
||||||
return v + roughness_ * (float) (rand_.nextGaussian() * (h - l));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// generate the fractal
|
|
||||||
private void generate(int xl, int yl, int xh, int yh) {
|
|
||||||
int xm = (xl + xh) / 2;
|
|
||||||
int ym = (yl + yh) / 2;
|
|
||||||
if ((xl == xm) && (yl == ym)) return;
|
|
||||||
|
|
||||||
grid_[xm][yl] = 0.5f * (grid_[xl][yl] + grid_[xh][yl]);
|
|
||||||
grid_[xm][yh] = 0.5f * (grid_[xl][yh] + grid_[xh][yh]);
|
|
||||||
grid_[xl][ym] = 0.5f * (grid_[xl][yl] + grid_[xl][yh]);
|
|
||||||
grid_[xh][ym] = 0.5f * (grid_[xh][yl] + grid_[xh][yh]);
|
|
||||||
|
|
||||||
float v = roughen(0.5f * (grid_[xm][yl] + grid_[xm][yh]), xl + yl, yh
|
|
||||||
+ xh);
|
|
||||||
grid_[xm][ym] = v;
|
|
||||||
grid_[xm][yl] = roughen(grid_[xm][yl], xl, xh);
|
|
||||||
grid_[xm][yh] = roughen(grid_[xm][yh], xl, xh);
|
|
||||||
grid_[xl][ym] = roughen(grid_[xl][ym], yl, yh);
|
|
||||||
grid_[xh][ym] = roughen(grid_[xh][ym], yl, yh);
|
|
||||||
|
|
||||||
generate(xl, yl, xm, ym);
|
|
||||||
generate(xm, yl, xh, ym);
|
|
||||||
generate(xl, ym, xm, yh);
|
|
||||||
generate(xm, ym, xh, yh);
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getValueAt(int x, int y) {
|
|
||||||
return grid_[x][y];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dump out as a CSV
|
|
||||||
*/
|
|
||||||
public void printAsCSV() {
|
|
||||||
for(int i = 0;i < grid_.length;i++) {
|
|
||||||
for(int j = 0;j < grid_[0].length;j++) {
|
|
||||||
System.out.print(grid_[i][j]);
|
|
||||||
System.out.print(",");
|
|
||||||
}
|
|
||||||
System.out.println();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert to a Boolean array
|
|
||||||
* @return the boolean array
|
|
||||||
*/
|
|
||||||
public boolean[][] toBooleans() {
|
|
||||||
int w = grid_.length;
|
|
||||||
int h = grid_[0].length;
|
|
||||||
boolean[][] ret = new boolean[w][h];
|
|
||||||
for(int i = 0;i < w;i++) {
|
|
||||||
for(int j = 0;j < h;j++) {
|
|
||||||
ret[i][j] = grid_[i][j] < 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
accessWidener v1 named
|
accessWidener v1 named
|
||||||
extendable class net/minecraft/world/gen/chunk/NoiseChunkGenerator
|
extendable class net/minecraft/world/gen/chunk/NoiseChunkGenerator
|
||||||
accessible class net/minecraft/world/gen/WorldPresets$Registrar
|
accessible class net/minecraft/world/gen/WorldPresets$Registrar
|
||||||
|
accessible class net/minecraft/inventory/Inventory
|
||||||
Reference in New Issue
Block a user