start caves
parent
cfbdab79c7
commit
bfe9767be9
|
@ -11,6 +11,7 @@ public class Block
|
|||
{ // add properties to this builder!
|
||||
private boolean visible = true;
|
||||
private boolean fullCube = true;
|
||||
private boolean canCaveCarve = false;
|
||||
private final String identifier;
|
||||
|
||||
public Properties(String identifier)
|
||||
|
@ -27,10 +28,16 @@ public class Block
|
|||
this.visible = visible;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Properties canCaveCarve(boolean canCaveCarve)
|
||||
{
|
||||
this.canCaveCarve = canCaveCarve;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public final TexturedModel model;
|
||||
private final boolean visible, fullCube;
|
||||
private final boolean visible, fullCube, canCaveCarve;
|
||||
public final String identifier;
|
||||
|
||||
public boolean isFullCube()
|
||||
|
@ -39,6 +46,9 @@ public class Block
|
|||
public boolean isVisible()
|
||||
{ return this.visible; }
|
||||
|
||||
public boolean canCaveCarve()
|
||||
{ return this.canCaveCarve; }
|
||||
|
||||
protected Block(Properties properties)
|
||||
{ this((TexturedModel) null, properties); }
|
||||
|
||||
|
@ -51,6 +61,7 @@ public class Block
|
|||
this.visible = properties.visible;
|
||||
this.fullCube = properties.fullCube;
|
||||
this.identifier = properties.identifier;
|
||||
this.canCaveCarve = properties.canCaveCarve;
|
||||
IDENTIFIER_TO_BLOCK.put(this.identifier, this);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,11 +5,11 @@ import com.github.halotroop.litecraft.types.block.Block.Properties;
|
|||
public final class Blocks
|
||||
{
|
||||
public static final Block AIR = new Block(new Properties("air").visible(false));
|
||||
public static final Block DIRT = new Block("block/cubes/soil/dirt.png", new Properties("dirt"));
|
||||
public static final Block ANDESITE = new Block("block/cubes/stone/basic/andesite.png", new Properties("andesite"));
|
||||
public static final Block DIORITE = new Block("block/cubes/stone/basic/diorite.png", new Properties("diorite"));
|
||||
public static final Block GRANITE = new Block("block/cubes/stone/basic/granite.png", new Properties("granite"));
|
||||
public static final Block GNEISS = new Block("block/cubes/stone/basic/gneiss.png", new Properties("gneiss"));
|
||||
public static final Block DIRT = new Block("block/cubes/soil/dirt.png", new Properties("dirt").canCaveCarve(true));
|
||||
public static final Block ANDESITE = new Block("block/cubes/stone/basic/andesite.png", new Properties("andesite").canCaveCarve(true));
|
||||
public static final Block DIORITE = new Block("block/cubes/stone/basic/diorite.png", new Properties("diorite").canCaveCarve(true));
|
||||
public static final Block GRANITE = new Block("block/cubes/stone/basic/granite.png", new Properties("granite").canCaveCarve(true));
|
||||
public static final Block GNEISS = new Block("block/cubes/stone/basic/gneiss.png", new Properties("gneiss").canCaveCarve(true));
|
||||
public static Block setup()
|
||||
{
|
||||
return AIR;
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.github.halotroop.litecraft.types.block.*;
|
|||
import com.github.halotroop.litecraft.world.block.BlockRenderer;
|
||||
import com.github.halotroop.litecraft.world.dimension.Dimension;
|
||||
import com.github.halotroop.litecraft.world.gen.*;
|
||||
import com.github.halotroop.litecraft.world.gen.modifier.WorldModifier;
|
||||
import com.github.hydos.ginger.engine.api.Ginger;
|
||||
import com.github.hydos.ginger.engine.elements.objects.Player;
|
||||
import com.github.hydos.ginger.engine.obj.ModelLoader;
|
||||
|
@ -29,6 +30,7 @@ public class World implements BlockAccess, WorldGenConstants
|
|||
public Player player;
|
||||
int renderBound;
|
||||
int renderBoundVertical;
|
||||
// dummy block instance for retrieving the default block model
|
||||
private final BlockInstance dummy;
|
||||
public World(long seed, int renderSize, Dimension<?> dim, LitecraftSave save)
|
||||
{
|
||||
|
@ -39,6 +41,11 @@ public class World implements BlockAccess, WorldGenConstants
|
|||
this.seed = seed;
|
||||
this.chunkGenerator = dim.createChunkGenerator(seed);
|
||||
this.worldModifiers = dim.getWorldModifierArray();
|
||||
// initialize world modifiers with seed
|
||||
for (WorldModifier modifier : this.worldModifiers)
|
||||
{
|
||||
modifier.initialize(seed);
|
||||
}
|
||||
this.genBlockAccess = new GenerationWorld(this);
|
||||
this.save = save;
|
||||
this.dimension = dim.id;
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.github.halotroop.litecraft.world.dimension;
|
|||
import java.util.*;
|
||||
|
||||
import com.github.halotroop.litecraft.world.gen.*;
|
||||
import com.github.halotroop.litecraft.world.gen.modifier.WorldModifier;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
|
||||
|
|
|
@ -4,5 +4,5 @@ import com.github.halotroop.litecraft.world.gen.*;
|
|||
|
||||
public final class Dimensions
|
||||
{
|
||||
public static final Dimension<EarthChunkGenerator> OVERWORLD = new EarthDimension(0, "earth");
|
||||
public static final Dimension<EarthChunkGenerator> OVERWORLD = new EarthDimension(0, "earth").addWorldModifier(new CavesModifier());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
package com.github.halotroop.litecraft.world.gen;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.github.halotroop.litecraft.types.block.Blocks;
|
||||
import com.github.halotroop.litecraft.util.noise.OctaveSimplexNoise;
|
||||
import com.github.halotroop.litecraft.world.BlockAccess;
|
||||
import com.github.halotroop.litecraft.world.gen.modifier.WorldModifier;
|
||||
|
||||
public class CavesModifier implements WorldModifier, WorldGenConstants
|
||||
{
|
||||
private OctaveSimplexNoise caveNoise;
|
||||
private static final double THRESHOLD = 0.3;
|
||||
//
|
||||
@Override
|
||||
public void initialize(long seed)
|
||||
{
|
||||
Random rand = new Random(seed);
|
||||
this.caveNoise = new OctaveSimplexNoise(rand, 2, 45.0, 1.0, 1.0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modifyWorld(BlockAccess world, Random rand, int chunkStartX, int chunkStartY, int chunkStartZ)
|
||||
{
|
||||
final int subChunks = CHUNK_SIZE >> 2; // in 4x4x4 blocks
|
||||
|
||||
for (int subChunkX = 0; subChunkX < subChunks; subChunkX++)
|
||||
{
|
||||
int scOffsetX = subChunkX << 2; // sub chunk offset x
|
||||
int scTotalX = scOffsetX + chunkStartX;
|
||||
for (int subChunkZ = 0; subChunkZ < subChunks; subChunkZ++)
|
||||
{
|
||||
int scOffsetZ = subChunkZ << 2; // sub chunk offset z
|
||||
int scTotalZ = scOffsetZ + chunkStartZ;
|
||||
for (int subChunkY = 0; subChunkY < subChunks; subChunkY++)
|
||||
{
|
||||
int scOffsetY = subChunkY << 2; // sub chunk offset y
|
||||
int scTotalY = scOffsetY + chunkStartY;
|
||||
// calculate noise at each corner of the cube [lower|upper][south|north][west|east]
|
||||
double noiseLSW = this.caveNoise.sample(scOffsetX, scOffsetY, scOffsetZ); // base = lower south west
|
||||
double noiseUSW = this.caveNoise.sample(scOffsetX, scOffsetY + 1, scOffsetZ);
|
||||
double noiseLNW = this.caveNoise.sample(scOffsetX, scOffsetY, scOffsetZ + 1);
|
||||
double noiseUNW = this.caveNoise.sample(scOffsetX, scOffsetY + 1, scOffsetZ + 1);
|
||||
double noiseLSE = this.caveNoise.sample(scOffsetX + 1, scOffsetY, scOffsetZ);
|
||||
double noiseUSE = this.caveNoise.sample(scOffsetX + 1, scOffsetY + 1, scOffsetZ);
|
||||
double noiseLNE = this.caveNoise.sample(scOffsetX + 1, scOffsetY, scOffsetZ + 1);
|
||||
double noiseUNE = this.caveNoise.sample(scOffsetX + 1, scOffsetY + 1, scOffsetZ + 1);
|
||||
// calculate y lerp progresses
|
||||
// lerp = low + progress * (high - low)
|
||||
double ypSW = 0.25 * (noiseUSW - noiseLSW);
|
||||
double ypNW = 0.25 * (noiseUNW - noiseLNW);
|
||||
double ypSE = 0.25 * (noiseUSE - noiseLSE);
|
||||
double ypNE = 0.25 * (noiseUNE - noiseLNE);
|
||||
// initial Y noises
|
||||
double ySW = noiseLSW;
|
||||
double ySE = noiseLSE;
|
||||
double yNW = noiseLNW;
|
||||
double yNE = noiseLNE;
|
||||
// loop over y, adding the progress each time
|
||||
for (int subY = 0; subY < 4; ++subY)
|
||||
{
|
||||
int totalY = subY + scTotalY;
|
||||
// calculate z lerp progresses
|
||||
double zpW = 0.25 * (yNW - ySW);
|
||||
double zpE = 0.25 * (yNE - ySE);
|
||||
// initial Z noises
|
||||
double zW = ySW;
|
||||
double zE = ySE;
|
||||
// loop over z, adding the progress each time
|
||||
for (int subZ = 0; subZ < 4; ++subZ)
|
||||
{
|
||||
int totalZ = subZ + scTotalZ;
|
||||
// calculate x lerp progress
|
||||
double lerpProg = 0.25 * (zE - zW);
|
||||
// initial x noise
|
||||
double lerpNoise = zW;
|
||||
// loop over x, adding the progress each time
|
||||
for (int subX = 0; subX < 4; ++subX)
|
||||
{
|
||||
int totalX = subX + scTotalX;
|
||||
// calculate whether to replace block with air
|
||||
// if the noise is within the threshold for caves
|
||||
if (lerpNoise > -THRESHOLD && lerpNoise < THRESHOLD)
|
||||
{
|
||||
// if the cave can carve into the block
|
||||
if (world.getBlock(totalX, totalY, totalZ).canCaveCarve())
|
||||
{
|
||||
world.setBlock(totalX, totalY, totalZ, Blocks.AIR);
|
||||
}
|
||||
}
|
||||
// add progress to the noise
|
||||
lerpNoise += lerpProg;
|
||||
}
|
||||
// add z progresses
|
||||
zW += zpW;
|
||||
zE += zpE;
|
||||
}
|
||||
// add y progresses
|
||||
ySW += ypSW;
|
||||
ySE += ypSE;
|
||||
yNW += ypNW;
|
||||
yNE += ypNE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.github.halotroop.litecraft.world.gen;
|
||||
package com.github.halotroop.litecraft.world.gen.modifier;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
|
@ -7,4 +7,5 @@ import com.github.halotroop.litecraft.world.BlockAccess;
|
|||
public interface WorldModifier
|
||||
{
|
||||
void modifyWorld(BlockAccess world, Random rand, int chunkStartX, int chunkStartY, int chunkStartZ);
|
||||
void initialize(long seed);
|
||||
}
|
Loading…
Reference in New Issue