Add world manifests
These include the spawn point, seed, and terrain generator so that you can load saved worlds with all the right details.
This commit is contained in:
parent
4d5509b734
commit
65deecd131
@ -10,6 +10,6 @@ namespace TrueCraft.API.World
|
|||||||
{
|
{
|
||||||
IList<IChunkDecorator> ChunkDecorators { get; }
|
IList<IChunkDecorator> ChunkDecorators { get; }
|
||||||
IChunk GenerateChunk(IWorld world, Coordinates2D coordinates);
|
IChunk GenerateChunk(IWorld world, Coordinates2D coordinates);
|
||||||
Vector3 SpawnPoint { get; }
|
Coordinates3D GetSpawn(IWorld world);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,6 +14,7 @@ namespace TrueCraft.API.World
|
|||||||
int Seed { get; set; }
|
int Seed { get; set; }
|
||||||
IBiomeMap BiomeDiagram { get; set; }
|
IBiomeMap BiomeDiagram { get; set; }
|
||||||
IChunkProvider ChunkProvider { get; set; }
|
IChunkProvider ChunkProvider { get; set; }
|
||||||
|
Coordinates3D SpawnPoint { get; set; }
|
||||||
long Time { get; set; }
|
long Time { get; set; }
|
||||||
|
|
||||||
event EventHandler<BlockChangeEventArgs> BlockChanged;
|
event EventHandler<BlockChangeEventArgs> BlockChanged;
|
||||||
|
@ -19,7 +19,6 @@ namespace TrueCraft.Core.TerrainGen
|
|||||||
public FlatlandGenerator()
|
public FlatlandGenerator()
|
||||||
{
|
{
|
||||||
GeneratorOptions = DefaultGeneratorOptions;
|
GeneratorOptions = DefaultGeneratorOptions;
|
||||||
SpawnPoint = new Vector3(0, 5, 0);
|
|
||||||
ChunkDecorators = new List<IChunkDecorator>();
|
ChunkDecorators = new List<IChunkDecorator>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +57,6 @@ namespace TrueCraft.Core.TerrainGen
|
|||||||
Layers.Add(generatorLayer);
|
Layers.Add(generatorLayer);
|
||||||
}
|
}
|
||||||
Biome = (Biome)byte.Parse(parts[2]);
|
Biome = (Biome)byte.Parse(parts[2]);
|
||||||
SpawnPoint = new Vector3(0, y, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IChunk GenerateChunk(IWorld world, Coordinates2D position)
|
public IChunk GenerateChunk(IWorld world, Coordinates2D position)
|
||||||
@ -97,7 +95,10 @@ namespace TrueCraft.Core.TerrainGen
|
|||||||
|
|
||||||
public IList<IChunkDecorator> ChunkDecorators { get; set; }
|
public IList<IChunkDecorator> ChunkDecorators { get; set; }
|
||||||
|
|
||||||
public Vector3 SpawnPoint { get; set; }
|
public Coordinates3D GetSpawn(IWorld world)
|
||||||
|
{
|
||||||
|
return Coordinates3D.Up * 5;
|
||||||
|
}
|
||||||
|
|
||||||
protected class GeneratorLayer
|
protected class GeneratorLayer
|
||||||
{
|
{
|
||||||
|
@ -16,7 +16,7 @@ namespace TrueCraft.Core.TerrainGen
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// This terrain generator is still under heavy development. Use at your own risk.
|
/// This terrain generator is still under heavy development. Use at your own risk.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class NewGenerator : IChunkProvider
|
public class StandardGenerator : IChunkProvider
|
||||||
{
|
{
|
||||||
BiomeRepository Biomes = new BiomeRepository();
|
BiomeRepository Biomes = new BiomeRepository();
|
||||||
Perlin HighNoise = new Perlin();
|
Perlin HighNoise = new Perlin();
|
||||||
@ -27,7 +27,8 @@ namespace TrueCraft.Core.TerrainGen
|
|||||||
ClampNoise BottomClamp;
|
ClampNoise BottomClamp;
|
||||||
ModifyNoise Modified;
|
ModifyNoise Modified;
|
||||||
private int GroundLevel = 50;
|
private int GroundLevel = 50;
|
||||||
public NewGenerator(bool SingleBiome = false, byte GenerateBiome = (byte)Biome.Plains)
|
|
||||||
|
public StandardGenerator(bool SingleBiome = false, byte GenerateBiome = (byte)Biome.Plains)
|
||||||
{
|
{
|
||||||
this.SingleBiome = SingleBiome;
|
this.SingleBiome = SingleBiome;
|
||||||
this.GenerationBiome = GenerateBiome;
|
this.GenerationBiome = GenerateBiome;
|
||||||
@ -71,25 +72,26 @@ namespace TrueCraft.Core.TerrainGen
|
|||||||
public Vector3 SpawnPoint { get; private set; }
|
public Vector3 SpawnPoint { get; private set; }
|
||||||
public bool SingleBiome { get; private set; }
|
public bool SingleBiome { get; private set; }
|
||||||
public byte GenerationBiome { get; private set; }
|
public byte GenerationBiome { get; private set; }
|
||||||
|
|
||||||
public IChunk GenerateChunk(IWorld world, Coordinates2D coordinates)
|
public IChunk GenerateChunk(IWorld world, Coordinates2D coordinates)
|
||||||
{
|
{
|
||||||
int FeaturePointDistance = 400;
|
const int featurePointDistance = 400;
|
||||||
int Seed = world.Seed;
|
int seed = world.Seed;
|
||||||
CellNoise Worley = new CellNoise();
|
var worley = new CellNoise();
|
||||||
Worley.Seed = Seed;
|
worley.Seed = seed;
|
||||||
HighNoise.Seed = Seed;
|
HighNoise.Seed = seed;
|
||||||
LowNoise.Seed = Seed;
|
LowNoise.Seed = seed;
|
||||||
var chunk = new Chunk(coordinates);
|
var chunk = new Chunk(coordinates);
|
||||||
for (int X = 0; X < 16; X++)
|
for (int X = 0; X < 16; X++)
|
||||||
{
|
{
|
||||||
for (int Z = 0; Z < 16; Z++)
|
for (int Z = 0; Z < 16; Z++)
|
||||||
{
|
{
|
||||||
var BlockX = MathHelper.ChunkToBlockX(X, coordinates.X);
|
var blockX = MathHelper.ChunkToBlockX(X, coordinates.X);
|
||||||
var BlockZ = MathHelper.ChunkToBlockZ(Z, coordinates.Z);
|
var blockZ = MathHelper.ChunkToBlockZ(Z, coordinates.Z);
|
||||||
double LowClampMid = LowClamp.MaxValue - ((LowClamp.MaxValue + LowClamp.MinValue) / 2);
|
const double lowClampRange = 5;
|
||||||
double LowClampRange = 5;
|
double lowClampMid = LowClamp.MaxValue - ((LowClamp.MaxValue + LowClamp.MinValue) / 2);
|
||||||
double LowClampValue = LowClamp.Value2D(BlockX, BlockZ);
|
double lowClampValue = LowClamp.Value2D(blockX, blockZ);
|
||||||
if (LowClampValue > LowClampMid - LowClampRange && LowClampValue < LowClampMid + LowClampRange)
|
if (lowClampValue > lowClampMid - lowClampRange && lowClampValue < lowClampMid + lowClampRange)
|
||||||
{
|
{
|
||||||
InvertNoise NewPrimary = new InvertNoise(HighClamp);
|
InvertNoise NewPrimary = new InvertNoise(HighClamp);
|
||||||
Modified.PrimaryNoise = NewPrimary;
|
Modified.PrimaryNoise = NewPrimary;
|
||||||
@ -100,23 +102,23 @@ namespace TrueCraft.Core.TerrainGen
|
|||||||
Modified = new ModifyNoise(HighClamp, LowClamp, NoiseModifier.Add);
|
Modified = new ModifyNoise(HighClamp, LowClamp, NoiseModifier.Add);
|
||||||
}
|
}
|
||||||
Modified = new ModifyNoise(Modified, BottomClamp, NoiseModifier.Subtract);
|
Modified = new ModifyNoise(Modified, BottomClamp, NoiseModifier.Subtract);
|
||||||
var CellValue = Worley.Value2D(BlockX, BlockZ);
|
var cellValue = worley.Value2D(blockX, blockZ);
|
||||||
var Location = new Coordinates2D(BlockX, BlockZ);
|
var location = new Coordinates2D(blockX, blockZ);
|
||||||
if (world.BiomeDiagram.BiomeCells.Count < 1 || CellValue.Equals(1) && world.BiomeDiagram.ClosestCellPoint(Location) >= FeaturePointDistance)
|
if (world.BiomeDiagram.BiomeCells.Count < 1 || cellValue.Equals(1) && world.BiomeDiagram.ClosestCellPoint(location) >= featurePointDistance)
|
||||||
{
|
{
|
||||||
byte ID = (SingleBiome) ? GenerationBiome : world.BiomeDiagram.GenerateBiome(Seed, Biomes, Location);
|
byte id = (SingleBiome) ? GenerationBiome : world.BiomeDiagram.GenerateBiome(seed, Biomes, location);
|
||||||
BiomeCell Cell = new BiomeCell(ID, Location);
|
BiomeCell Cell = new BiomeCell(id, location);
|
||||||
world.BiomeDiagram.AddCell(Cell);
|
world.BiomeDiagram.AddCell(Cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
var BiomeID = GetBiome(world, Location);
|
var biomeId = GetBiome(world, location);
|
||||||
IBiomeProvider Biome = Biomes.GetBiome(BiomeID);
|
IBiomeProvider Biome = Biomes.GetBiome(biomeId);
|
||||||
chunk.Biomes[X * Chunk.Width + Z] = BiomeID;
|
chunk.Biomes[X * Chunk.Width + Z] = biomeId;
|
||||||
|
|
||||||
var Height = GetHeight(BlockX, BlockZ);
|
var height = GetHeight(blockX, blockZ);
|
||||||
var SurfaceHeight = Height - Biome.SurfaceDepth;
|
var surfaceHeight = height - Biome.SurfaceDepth;
|
||||||
chunk.HeightMap[X * Chunk.Width + Z] = Height;
|
chunk.HeightMap[X * Chunk.Width + Z] = height;
|
||||||
for (int Y = 0; Y <= Height; Y++)
|
for (int Y = 0; Y <= height; Y++)
|
||||||
{
|
{
|
||||||
if (Y == 0)
|
if (Y == 0)
|
||||||
{
|
{
|
||||||
@ -124,13 +126,13 @@ namespace TrueCraft.Core.TerrainGen
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Y.Equals(Height) || Y < Height && Y > SurfaceHeight)
|
if (Y.Equals(height) || Y < height && Y > surfaceHeight)
|
||||||
{
|
{
|
||||||
chunk.SetBlockID(new Coordinates3D(X, Y, Z), Biome.SurfaceBlock);
|
chunk.SetBlockID(new Coordinates3D(X, Y, Z), Biome.SurfaceBlock);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Y > SurfaceHeight - Biome.FillerDepth)
|
if (Y > surfaceHeight - Biome.FillerDepth)
|
||||||
{
|
{
|
||||||
chunk.SetBlockID(new Coordinates3D(X, Y, Z), Biome.FillerBlock);
|
chunk.SetBlockID(new Coordinates3D(X, Y, Z), Biome.FillerBlock);
|
||||||
}
|
}
|
||||||
@ -144,29 +146,27 @@ namespace TrueCraft.Core.TerrainGen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (IChunkDecorator ChunkDecorator in ChunkDecorators)
|
foreach (IChunkDecorator ChunkDecorator in ChunkDecorators)
|
||||||
{
|
|
||||||
ChunkDecorator.Decorate(world, chunk, Biomes);
|
ChunkDecorator.Decorate(world, chunk, Biomes);
|
||||||
}
|
|
||||||
var SpawnOffset = 2;
|
|
||||||
var SpawnPointHeight = GetHeight(0, 0);
|
|
||||||
if (SpawnPointHeight + SpawnOffset < Chunk.Height)
|
|
||||||
SpawnPointHeight += SpawnOffset;
|
|
||||||
SpawnPoint = new Vector3(0, SpawnPointHeight, 0);
|
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte GetBiome(IWorld world, Coordinates2D Location)
|
public Coordinates3D GetSpawn(IWorld world)
|
||||||
{
|
{
|
||||||
if (SingleBiome)
|
var chunk = GenerateChunk(world, Coordinates2D.Zero);
|
||||||
{
|
var spawnPointHeight = chunk.HeightMap[0];
|
||||||
return GenerationBiome;
|
return new Coordinates3D(0, spawnPointHeight + 1, 0);
|
||||||
}
|
|
||||||
return world.BiomeDiagram.GetBiome(Location);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetHeight(int X, int Z)
|
byte GetBiome(IWorld world, Coordinates2D location)
|
||||||
{
|
{
|
||||||
var NoiseValue = Modified.Value2D(X, Z) + GroundLevel;
|
if (SingleBiome)
|
||||||
|
return GenerationBiome;
|
||||||
|
return world.BiomeDiagram.GetBiome(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetHeight(int x, int z)
|
||||||
|
{
|
||||||
|
var NoiseValue = Modified.Value2D(x, z) + GroundLevel;
|
||||||
if (NoiseValue < 0)
|
if (NoiseValue < 0)
|
||||||
NoiseValue = GroundLevel;
|
NoiseValue = GroundLevel;
|
||||||
if (NoiseValue > Chunk.Height)
|
if (NoiseValue > Chunk.Height)
|
@ -206,7 +206,6 @@
|
|||||||
<Compile Include="TerrainGen\Noise\Perlin.cs" />
|
<Compile Include="TerrainGen\Noise\Perlin.cs" />
|
||||||
<Compile Include="TerrainGen\Noise\ScaleNoise.cs" />
|
<Compile Include="TerrainGen\Noise\ScaleNoise.cs" />
|
||||||
<Compile Include="TerrainGen\Noise\CellNoise.cs" />
|
<Compile Include="TerrainGen\Noise\CellNoise.cs" />
|
||||||
<Compile Include="TerrainGen\NewGenerator.cs" />
|
|
||||||
<Compile Include="World\BiomeMap.cs" />
|
<Compile Include="World\BiomeMap.cs" />
|
||||||
<Compile Include="World\Chunk.cs" />
|
<Compile Include="World\Chunk.cs" />
|
||||||
<Compile Include="World\Region.cs" />
|
<Compile Include="World\Region.cs" />
|
||||||
@ -309,6 +308,7 @@
|
|||||||
<Compile Include="Logic\Blocks\FluidBlock.cs" />
|
<Compile Include="Logic\Blocks\FluidBlock.cs" />
|
||||||
<Compile Include="Entities\FallingSandEntity.cs" />
|
<Compile Include="Entities\FallingSandEntity.cs" />
|
||||||
<Compile Include="Logic\Blocks\DoorBlock.cs" />
|
<Compile Include="Logic\Blocks\DoorBlock.cs" />
|
||||||
|
<Compile Include="TerrainGen\StandardGenerator.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -6,6 +6,7 @@ using System.Threading;
|
|||||||
using TrueCraft.API;
|
using TrueCraft.API;
|
||||||
using TrueCraft.API.World;
|
using TrueCraft.API.World;
|
||||||
using TrueCraft.API.Logic;
|
using TrueCraft.API.Logic;
|
||||||
|
using fNbt;
|
||||||
|
|
||||||
namespace TrueCraft.Core.World
|
namespace TrueCraft.Core.World
|
||||||
{
|
{
|
||||||
@ -15,12 +16,14 @@ namespace TrueCraft.Core.World
|
|||||||
|
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public int Seed { get; set; }
|
public int Seed { get; set; }
|
||||||
|
public Coordinates3D SpawnPoint { get; set; }
|
||||||
public string BaseDirectory { get; internal set; }
|
public string BaseDirectory { get; internal set; }
|
||||||
public IDictionary<Coordinates2D, IRegion> Regions { get; set; }
|
public IDictionary<Coordinates2D, IRegion> Regions { get; set; }
|
||||||
public IBiomeMap BiomeDiagram { get; set; }
|
public IBiomeMap BiomeDiagram { get; set; }
|
||||||
public IChunkProvider ChunkProvider { get; set; }
|
public IChunkProvider ChunkProvider { get; set; }
|
||||||
public IBlockRepository BlockRepository { get; set; }
|
public IBlockRepository BlockRepository { get; set; }
|
||||||
public DateTime BaseTime { get; set; }
|
public DateTime BaseTime { get; set; }
|
||||||
|
|
||||||
public long Time
|
public long Time
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -47,6 +50,7 @@ namespace TrueCraft.Core.World
|
|||||||
public World(string name, IChunkProvider chunkProvider) : this(name)
|
public World(string name, IChunkProvider chunkProvider) : this(name)
|
||||||
{
|
{
|
||||||
ChunkProvider = chunkProvider;
|
ChunkProvider = chunkProvider;
|
||||||
|
SpawnPoint = chunkProvider.GetSpawn(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static World LoadWorld(string baseDirectory)
|
public static World LoadWorld(string baseDirectory)
|
||||||
@ -55,6 +59,17 @@ namespace TrueCraft.Core.World
|
|||||||
throw new DirectoryNotFoundException();
|
throw new DirectoryNotFoundException();
|
||||||
var world = new World(Path.GetFileName(baseDirectory));
|
var world = new World(Path.GetFileName(baseDirectory));
|
||||||
world.BaseDirectory = baseDirectory;
|
world.BaseDirectory = baseDirectory;
|
||||||
|
if (File.Exists(Path.Combine(baseDirectory, "manifest.nbt")))
|
||||||
|
{
|
||||||
|
var file = new NbtFile(Path.Combine(baseDirectory, "manifest.nbt"));
|
||||||
|
world.SpawnPoint = new Coordinates3D(file.RootTag["SpawnPoint"]["X"].IntValue,
|
||||||
|
file.RootTag["SpawnPoint"]["Y"].IntValue,
|
||||||
|
file.RootTag["SpawnPoint"]["Z"].IntValue);
|
||||||
|
world.Seed = file.RootTag["Seed"].IntValue;
|
||||||
|
var providerName = file.RootTag["ChunkProvider"].StringValue;
|
||||||
|
var provider = (IChunkProvider)Activator.CreateInstance(Type.GetType(providerName), world);
|
||||||
|
world.ChunkProvider = provider;
|
||||||
|
}
|
||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,6 +238,16 @@ namespace TrueCraft.Core.World
|
|||||||
foreach (var region in Regions)
|
foreach (var region in Regions)
|
||||||
region.Value.Save(Path.Combine(BaseDirectory, Region.GetRegionFileName(region.Key)));
|
region.Value.Save(Path.Combine(BaseDirectory, Region.GetRegionFileName(region.Key)));
|
||||||
}
|
}
|
||||||
|
var file = new NbtFile();
|
||||||
|
file.RootTag.Add(new NbtCompound("SpawnPoint", new[]
|
||||||
|
{
|
||||||
|
new NbtInt("X", this.SpawnPoint.X),
|
||||||
|
new NbtInt("Y", this.SpawnPoint.Y),
|
||||||
|
new NbtInt("Z", this.SpawnPoint.Z)
|
||||||
|
}));
|
||||||
|
file.RootTag.Add(new NbtInt("Seed", this.Seed));
|
||||||
|
file.RootTag.Add(new NbtString("ChunkProvider", this.ChunkProvider.GetType().FullName));
|
||||||
|
file.SaveToFile(Path.Combine(this.BaseDirectory, "manifest.nbt"), NbtCompression.ZLib);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Save(string path)
|
public void Save(string path)
|
||||||
@ -230,11 +255,7 @@ namespace TrueCraft.Core.World
|
|||||||
if (!Directory.Exists(path))
|
if (!Directory.Exists(path))
|
||||||
Directory.CreateDirectory(path);
|
Directory.CreateDirectory(path);
|
||||||
BaseDirectory = path;
|
BaseDirectory = path;
|
||||||
lock (Regions)
|
Save();
|
||||||
{
|
|
||||||
foreach (var region in Regions)
|
|
||||||
region.Value.Save(Path.Combine(BaseDirectory, Region.GetRegionFileName(region.Key)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Coordinates3D FindBlockPosition(Coordinates3D coordinates, out IChunk chunk)
|
public Coordinates3D FindBlockPosition(Coordinates3D coordinates, out IChunk chunk)
|
||||||
|
@ -39,7 +39,7 @@ namespace TrueCraft.Handlers
|
|||||||
client.QueuePacket(new LoginResponsePacket(0, 0, Dimension.Overworld));
|
client.QueuePacket(new LoginResponsePacket(0, 0, Dimension.Overworld));
|
||||||
client.UpdateChunks();
|
client.UpdateChunks();
|
||||||
client.QueuePacket(new WindowItemsPacket(0, client.Inventory.GetSlots()));
|
client.QueuePacket(new WindowItemsPacket(0, client.Inventory.GetSlots()));
|
||||||
client.Entity.Position = client.World.ChunkProvider.SpawnPoint;
|
client.Entity.Position = client.World.SpawnPoint;
|
||||||
client.QueuePacket(new SpawnPositionPacket((int)client.Entity.Position.X,
|
client.QueuePacket(new SpawnPositionPacket((int)client.Entity.Position.X,
|
||||||
(int)client.Entity.Position.Y, (int)client.Entity.Position.Z));
|
(int)client.Entity.Position.Y, (int)client.Entity.Position.Z));
|
||||||
client.QueuePacket(new SetPlayerPositionPacket(client.Entity.Position.X, client.Entity.Position.Y,
|
client.QueuePacket(new SetPlayerPositionPacket(client.Entity.Position.X, client.Entity.Position.Y,
|
||||||
|
@ -26,11 +26,11 @@ namespace TrueCraft
|
|||||||
{
|
{
|
||||||
// TODO: Save and load levels, with seeds and everything
|
// TODO: Save and load levels, with seeds and everything
|
||||||
world = World.LoadWorld("world");
|
world = World.LoadWorld("world");
|
||||||
world.ChunkProvider = new NewGenerator();
|
world.ChunkProvider = new StandardGenerator();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
world = new World("default", new NewGenerator());
|
world = new World("default", new StandardGenerator());
|
||||||
world.Save("world");
|
world.Save("world");
|
||||||
}
|
}
|
||||||
server.AddWorld(world);
|
server.AddWorld(world);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user