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