diff --git a/TrueCraft.API/World/IChunk.cs b/TrueCraft.API/World/IChunk.cs
index 08f729a..2cb9388 100644
--- a/TrueCraft.API/World/IChunk.cs
+++ b/TrueCraft.API/World/IChunk.cs
@@ -4,16 +4,10 @@ using System.Collections.Generic;
namespace TrueCraft.API.World
{
- public interface IChunk : IEventSubject, IDisposable
+ public interface IChunk : IEventSubject, IDisposable, ISpatialBlockInformationProvider
{
- int X { get; }
- int Z { get; }
- int MaxHeight { get; }
- Coordinates2D Coordinates { get; set; }
bool IsModified { get; set; }
bool LightPopulated { get; set; }
- int[] HeightMap { get; }
- byte[] Biomes { get; }
DateTime LastAccessed { get; set; }
byte[] Data { get; }
bool TerrainPopulated { get; set; }
@@ -22,14 +16,9 @@ namespace TrueCraft.API.World
NibbleSlice BlockLight { get; }
NibbleSlice SkyLight { get; }
IRegion ParentRegion { get; set; }
- int GetHeight(byte x, byte z);
void UpdateHeightMap();
- byte GetBlockID(Coordinates3D coordinates);
- byte GetMetadata(Coordinates3D coordinates);
byte GetSkyLight(Coordinates3D coordinates);
byte GetBlockLight(Coordinates3D coordinates);
- void SetBlockID(Coordinates3D coordinates, byte value);
- void SetMetadata(Coordinates3D coordinates, byte value);
void SetSkyLight(Coordinates3D coordinates, byte value);
void SetBlockLight(Coordinates3D coordinates, byte value);
NbtCompound GetTileEntity(Coordinates3D coordinates);
diff --git a/TrueCraft.API/World/IChunkDecorator.cs b/TrueCraft.API/World/IChunkDecorator.cs
index 412926f..7a968c5 100644
--- a/TrueCraft.API/World/IChunkDecorator.cs
+++ b/TrueCraft.API/World/IChunkDecorator.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using TrueCraft.API.Logic;
namespace TrueCraft.API.World
{
@@ -10,6 +11,6 @@ namespace TrueCraft.API.World
///
public interface IChunkDecorator
{
- void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes);
+ void Decorate(IWorldSeed world, ISpatialBlockInformationProvider chunk, IBiomeRepository biomes, IBlockRepository blockRepository);
}
}
diff --git a/TrueCraft.API/World/IDecoration.cs b/TrueCraft.API/World/IDecoration.cs
index bd87e45..86e311f 100644
--- a/TrueCraft.API/World/IDecoration.cs
+++ b/TrueCraft.API/World/IDecoration.cs
@@ -8,6 +8,6 @@ namespace TrueCraft.API.World
public interface IDecoration
{
bool ValidLocation(Coordinates3D location);
- bool GenerateAt(IWorld world, IChunk chunk, Coordinates3D location);
+ bool GenerateAt(IWorldSeed world, ISpatialBlockInformationProvider chunk, Coordinates3D location);
}
}
\ No newline at end of file
diff --git a/TrueCraft.API/World/ISpatialBlockInformationProvider.cs b/TrueCraft.API/World/ISpatialBlockInformationProvider.cs
new file mode 100644
index 0000000..f0e65ce
--- /dev/null
+++ b/TrueCraft.API/World/ISpatialBlockInformationProvider.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TrueCraft.API.World
+{
+ public interface ISpatialBlockInformationProvider
+ {
+ int X {get;}
+ int Z { get; }
+ int MaxHeight { get; }
+
+ int[] HeightMap { get; }
+
+ byte[] Biomes { get; }
+
+
+ int GetHeight(byte x, byte z);
+
+
+ // This is really all one related concept.
+ byte GetBlockID(Coordinates3D coordinates);
+ void SetBlockID(Coordinates3D coordinates, byte value);
+ byte GetMetadata(Coordinates3D locationToCheck);
+ void SetMetadata(Coordinates3D blockLocation, byte meta);
+
+ Coordinates2D Coordinates { get; set; }
+ }
+}
diff --git a/TrueCraft.API/World/IWorld.cs b/TrueCraft.API/World/IWorld.cs
index 5b4c643..f32827f 100644
--- a/TrueCraft.API/World/IWorld.cs
+++ b/TrueCraft.API/World/IWorld.cs
@@ -9,11 +9,10 @@ namespace TrueCraft.API.World
///
/// An in-game world composed of chunks and blocks.
///
- public interface IWorld : IEnumerable
+ public interface IWorld : IEnumerable, IWorldSeed
{
string Name { get; set; }
IBlockRepository BlockRepository { get; set; }
- int Seed { get; set; }
IBiomeMap BiomeDiagram { get; set; }
IChunkProvider ChunkProvider { get; set; }
Coordinates3D SpawnPoint { get; set; }
@@ -42,4 +41,9 @@ namespace TrueCraft.API.World
void Save();
void Save(string path);
}
+
+ public interface IWorldSeed
+ {
+ int Seed { get; set; }
+ }
}
\ No newline at end of file
diff --git a/TrueCraft.Core.Test/TrueCraft.Core.Test.csproj b/TrueCraft.Core.Test/TrueCraft.Core.Test.csproj
index b516541..6b8150f 100644
--- a/TrueCraft.Core.Test/TrueCraft.Core.Test.csproj
+++ b/TrueCraft.Core.Test/TrueCraft.Core.Test.csproj
@@ -1,4 +1,4 @@
-
+
Debug
@@ -81,9 +81,14 @@
+
+
+
+
+
@@ -92,13 +97,5 @@
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/TrueCraft.Core.Test/World/SugarCaneDecoratorTests.cs b/TrueCraft.Core.Test/World/SugarCaneDecoratorTests.cs
new file mode 100644
index 0000000..70e3de7
--- /dev/null
+++ b/TrueCraft.Core.Test/World/SugarCaneDecoratorTests.cs
@@ -0,0 +1,159 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Moq;
+using NUnit.Framework;
+using TrueCraft.API;
+using TrueCraft.API.World;
+using TrueCraft.Core.Logic.Blocks;
+using TrueCraft.Core.TerrainGen;
+using TrueCraft.Core.TerrainGen.Biomes;
+using TrueCraft.Core.TerrainGen.Decorators;
+using TrueCraft.Core.Test.Logic;
+using TrueCraft.Core.Test.World.TestFakes;
+using TrueCraft.Core.World;
+
+namespace TrueCraft.Core.Test.World
+{
+ [TestFixture]
+ public class SugarCaneDecoratorTests
+ {
+ [Test]
+ public void DecoratorGrowsNoInvalidSugarCane()
+ {
+ var aWorld = new WorldWithJustASeed(9001);
+ ISpatialBlockInformationProvider aChunk = new PrimeSugarCaneGrowingSeasonChunk();
+ IBiomeRepository aBiomeRepository = new BiomeRepository();
+ var decorator = GetDecoratorForTestChunk(aWorld, aChunk, aBiomeRepository);
+
+ decorator.Decorate(aWorld, aChunk, aBiomeRepository, null /* Don't need to fake it if you don't use it. */);
+
+ AssertChunkHasNoSugarCaneInColumnsWhereItShouldNot(aChunk);
+ }
+
+ [Test]
+ public void DecoratorDoesNotGrowSugarcaneUniformly()
+ {
+ IWorldSeed aWorld = new WorldWithJustASeed(9001);
+ ISpatialBlockInformationProvider aChunk = new PrimeSugarCaneGrowingSeasonChunk();
+ IBiomeRepository aBiomeRepository = new BiomeRepository();
+ var decorator = GetDecoratorForTestChunk(aWorld, aChunk, aBiomeRepository);
+
+ decorator.Decorate(aWorld, aChunk, aBiomeRepository, null);
+
+ AssertChunkSugarCaneGrowthIsNotUniform(aChunk);
+ }
+
+ private void AssertChunkHasNoSugarCaneInColumnsWhereItShouldNot(ISpatialBlockInformationProvider aChunk)
+ {
+ for (int x = 0; x < 6; x++)
+ {
+ for (int z = 0; z < 6; z++)
+ {
+ Coordinates2D coord = new Coordinates2D(x, z);
+ if (PrimeSugarCaneGrowingSeasonChunk.PointsWithoutAnySugarcane().Contains(coord))
+ {
+ Assert.AreEqual(0, CountBlockInColumn(aChunk, x, z, SugarcaneBlock.BlockID), string.Format("Sugarcane in column ({0},{1})", x,z));
+ }
+ }
+ }
+ }
+
+ private void AssertChunkSugarCaneGrowthIsNotUniform(ISpatialBlockInformationProvider aChunk)
+ {
+ var counts = new List();
+ for (int x = 0; x < 6; x++)
+ {
+ for (int z = 0; z < 6; z++)
+ {
+ Coordinates2D coord = new Coordinates2D(x, z);
+ var countOfSugarCane = CountBlockInColumn(aChunk, x, z, SugarcaneBlock.BlockID);
+ if (countOfSugarCane != 0)
+ {
+ counts.Add(countOfSugarCane);
+ }
+ }
+ }
+ double averageOfSugarCaneHeight = counts.Average();
+
+ for (int i = 0; i < 7; i++)
+ {
+ Assert.AreNotEqual(i, averageOfSugarCaneHeight, "Sugarcane grew with uniform height.");
+ }
+ }
+
+ private static SugarCaneDecorator GetDecoratorForTestChunk(IWorldSeed aWorld, ISpatialBlockInformationProvider aChunk,
+ IBiomeRepository aBiomeRepository)
+ {
+ var decorator = new SugarCaneDecorator(new NoiseAlwaysGrowsSugarCaneInTestBounds());
+ aBiomeRepository.RegisterBiomeProvider(new SwamplandBiome());
+ return decorator;
+ }
+
+ static int CountBlockInColumn(ISpatialBlockInformationProvider aChunk, int x, int z, byte blockId)
+ {
+ int counter = 0;
+
+ for (int y = 0; y < 7; y++)
+ {
+ byte block = aChunk.GetBlockID(new Coordinates3D(x: x, y: y, z: z));
+ if (block == blockId)
+ {
+ counter++;
+ }
+ }
+ return counter;
+ }
+
+ [Test]
+ public void TestUsingAMock()
+ {
+ Mock aWorld = new Mock();
+ aWorld.Setup(foo => foo.Seed).Returns(9001);
+
+ var ourDictionary = PrimeSugarCaneGrowingSeasonChunk.createStartingBlockDictionary();
+
+ Mock aChunk = new Mock();
+
+ aChunk.Setup(foo => foo.GetBlockID(It.IsAny())).Returns((Coordinates3D coordinates) =>
+ {
+ if (ourDictionary.ContainsKey(coordinates))
+ {
+ return ourDictionary[coordinates];
+ }
+ return AirBlock.BlockID;
+ });
+
+ aChunk.Setup(foo => foo.SetBlockID(It.IsAny(),
+ It.IsAny())).Callback((a, b) =>
+ {
+ ourDictionary[a] = b;
+ });
+
+ aChunk.Setup(chunk => chunk.X).Returns(6);
+ aChunk.Setup(chunk => chunk.Z).Returns(6);
+ aChunk.Setup(chunk => chunk.MaxHeight).Returns(6);
+
+ aChunk.Setup(chunk => chunk.HeightMap).Returns(() =>
+ {
+ return Enumerable.Repeat(1, Chunk.Width * Chunk.Height).ToArray();
+ });
+
+ aChunk.Setup(chunk => chunk.Biomes).Returns(() =>
+ {
+ return Enumerable.Repeat(new SwamplandBiome().ID, Chunk.Width * Chunk.Height).ToArray();
+ });
+
+ aChunk.Setup(chunk => chunk.GetHeight(It.IsAny(), It.IsAny())).Returns(1);
+
+
+
+ IBiomeRepository aBiomeRepository = new BiomeRepository();
+ var decorator = GetDecoratorForTestChunk(aWorld.Object, aChunk.Object, aBiomeRepository);
+
+ decorator.Decorate(aWorld.Object, aChunk.Object, aBiomeRepository, null);
+
+ AssertChunkSugarCaneGrowthIsNotUniform(aChunk.Object);
+ }
+ }
+}
\ No newline at end of file
diff --git a/TrueCraft.Core.Test/World/TestFakes/NoiseAlwaysGrowsSugarCaneInTestBounds.cs b/TrueCraft.Core.Test/World/TestFakes/NoiseAlwaysGrowsSugarCaneInTestBounds.cs
new file mode 100644
index 0000000..70969bd
--- /dev/null
+++ b/TrueCraft.Core.Test/World/TestFakes/NoiseAlwaysGrowsSugarCaneInTestBounds.cs
@@ -0,0 +1,19 @@
+using TrueCraft.Core.TerrainGen.Noise;
+
+namespace TrueCraft.Core.Test.World.TestFakes
+{
+ public class NoiseAlwaysGrowsSugarCaneInTestBounds : NoiseGen
+ {
+ public override double Value2D(double x, double y)
+ {
+ return x > 5 ? 0 : (y > 5 ? 0 : 1);
+ }
+
+ public override double Value3D(double x, double y, double z)
+ {
+ double value2d = Value2D(x, y);
+
+ return 1;
+ }
+ }
+}
diff --git a/TrueCraft.Core.Test/World/TestFakes/PrimeSugarCaneGrowingSeasonChunk.cs b/TrueCraft.Core.Test/World/TestFakes/PrimeSugarCaneGrowingSeasonChunk.cs
new file mode 100644
index 0000000..b64fa5d
--- /dev/null
+++ b/TrueCraft.Core.Test/World/TestFakes/PrimeSugarCaneGrowingSeasonChunk.cs
@@ -0,0 +1,179 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using fNbt;
+using TrueCraft.API;
+using TrueCraft.API.World;
+using TrueCraft.Core.Logic.Blocks;
+using TrueCraft.Core.TerrainGen.Biomes;
+using TrueCraft.Core.World;
+
+public class PrimeSugarCaneGrowingSeasonChunk : ISpatialBlockInformationProvider
+{
+ public int X => 6;
+ public int Z => 6;
+ public int MaxHeight => 7;
+
+ public int[] HeightMap => Enumerable.Repeat(1, Chunk.Width * Chunk.Height).ToArray();
+ public byte[] Biomes => Enumerable.Repeat(new SwamplandBiome().ID, Chunk.Width * Chunk.Height).ToArray();
+
+ public int GetHeight(byte x, byte z)
+ {
+ // Pretty sure this is always one since we have a flat surface
+ // (Unless water heights are reported differently)
+ return 1;
+ }
+
+ private Dictionary blockDictionary = createStartingBlockDictionary();
+
+ public byte GetBlockID(Coordinates3D coordinates)
+ {
+ if (blockDictionary.ContainsKey(coordinates))
+ {
+ return blockDictionary[coordinates];
+ }
+ return AirBlock.BlockID;
+ }
+
+ public void SetBlockID(Coordinates3D coordinates, byte value)
+ {
+ blockDictionary[coordinates] = value;
+ }
+
+ public int GetMetadata(Coordinates3D locationToCheck)
+ {
+ return -1;
+ }
+
+ public void SetMetadata(Coordinates3D blockLocation, byte meta)
+ {
+ //
+ }
+
+ public Coordinates2D Coordinates { get; set; }
+
+ public static int CountBlockInColumn(Dictionary aChunk, int x, int z, byte blockId)
+ {
+ int counter = 0;
+
+ for (int y = 0; y < 7; y++)
+ {
+ byte block = aChunk[new Coordinates3D(x: x, y: y, z: z)];
+ if (block == blockId)
+ {
+ counter++;
+ }
+ }
+ return counter;
+ }
+
+ private static byte MapXZToTestBlock(int X, int Z)
+ {
+ // Sand on the outer left hand side
+ if (X == 0)
+ {
+ return GrassBlock.BlockID;
+ }
+
+ // Sand on the outer right hand side
+ if (X == 5)
+ {
+ return SandBlock.BlockID;
+ }
+
+ if (Z == 0)
+ return WaterBlock.BlockID;
+
+ if (Z == 3)
+ return StationaryWaterBlock.BlockID;
+
+ switch (X)
+ {
+ case 1:
+ return GrassBlock.BlockID;
+ case 2:
+ return DirtBlock.BlockID;
+ case 3:
+ return SandBlock.BlockID;
+ case 4:
+ return StoneBlock.BlockID;
+ }
+
+ return DiamondBlock.BlockID;
+ }
+
+ public static Dictionary createStartingBlockDictionary()
+ {
+ int xBounds = 6;
+ int yBounds = 7;
+ int zBounds = 6;
+
+ Dictionary blockDictionary = new Dictionary();
+
+ for (int x = 0; x < xBounds; x++)
+ {
+ for (int z = 0; z < zBounds; z++)
+ {
+ byte row1Blocks = MapXZToTestBlock(x, z);
+ for (int y = 0; y < yBounds; y++)
+ {
+ byte blockToStore = AirBlock.BlockID;
+ if (y == 0)
+ {
+ // Dirt on the lowest layer
+ blockToStore = DirtBlock.BlockID;
+ }
+ if (y == 1)
+ {
+ blockToStore = row1Blocks;
+ }
+ blockDictionary.Add(new Coordinates3D(x, y, z), blockToStore);
+ }
+ }
+ }
+
+ return blockDictionary;
+ }
+
+ public static HashSet PointsWithoutAnySugarcane()
+ {
+ var result = new HashSet();
+ var startingDictionary = createStartingBlockDictionary();
+ foreach (var block in createStartingBlockDictionary())
+ {
+ var placesToGrow = CountBlockInColumn(startingDictionary, block.Key.X, block.Key.Z, SandBlock.BlockID);
+ placesToGrow += CountBlockInColumn(startingDictionary, block.Key.X, block.Key.Z, GrassBlock.BlockID);
+
+ if (placesToGrow == 0)
+ {
+ result.Add(new Coordinates2D(block.Key.X, block.Key.Z));
+ }
+ }
+
+ result.Add(new Coordinates2D(0, 0));
+ result.Add(new Coordinates2D(0, 1));
+ result.Add(new Coordinates2D(0, 0));
+ result.Add(new Coordinates2D(0, 2));
+ result.Add(new Coordinates2D(0, 4));
+ result.Add(new Coordinates2D(0, 5));
+
+
+ for (int i = 1; i < 5; i++)
+ {
+ // Top row of the test data is all landlocked
+ result.Add(new Coordinates2D(i, 5));
+ }
+
+ result.Add(new Coordinates2D(5, 5));
+ result.Add(new Coordinates2D(5, 4));
+ result.Add(new Coordinates2D(5, 2));
+ result.Add(new Coordinates2D(5, 1));
+
+ return result;
+ }
+
+ byte ISpatialBlockInformationProvider.GetMetadata(Coordinates3D locationToCheck)
+ {
+ throw new NotImplementedException();
+ }
+}
diff --git a/TrueCraft.Core.Test/World/TestFakes/WorldWithJustASeed.cs b/TrueCraft.Core.Test/World/TestFakes/WorldWithJustASeed.cs
new file mode 100644
index 0000000..901df55
--- /dev/null
+++ b/TrueCraft.Core.Test/World/TestFakes/WorldWithJustASeed.cs
@@ -0,0 +1,15 @@
+
+using TrueCraft.API.World;
+
+namespace TrueCraft.Core.Test.World.TestFakes
+{
+ public class WorldWithJustASeed : IWorldSeed
+ {
+ public WorldWithJustASeed(int seed)
+ {
+ this.Seed = seed;
+ }
+
+ public int Seed { get; set; }
+ }
+}
diff --git a/TrueCraft.Core/TerrainGen/Decorations/BalloonOakTree.cs b/TrueCraft.Core/TerrainGen/Decorations/BalloonOakTree.cs
index 6937cb6..7a226c0 100644
--- a/TrueCraft.Core/TerrainGen/Decorations/BalloonOakTree.cs
+++ b/TrueCraft.Core/TerrainGen/Decorations/BalloonOakTree.cs
@@ -26,7 +26,7 @@ namespace TrueCraft.Core.TerrainGen.Decorations
return true;
}
- public override bool GenerateAt(IWorld world, IChunk chunk, Coordinates3D location)
+ public override bool GenerateAt(IWorldSeed world, ISpatialBlockInformationProvider chunk, Coordinates3D location)
{
if (!ValidLocation(location))
return false;
diff --git a/TrueCraft.Core/TerrainGen/Decorations/BirchTree.cs b/TrueCraft.Core/TerrainGen/Decorations/BirchTree.cs
index 889ba16..5cdc342 100644
--- a/TrueCraft.Core/TerrainGen/Decorations/BirchTree.cs
+++ b/TrueCraft.Core/TerrainGen/Decorations/BirchTree.cs
@@ -25,7 +25,7 @@ namespace TrueCraft.Core.TerrainGen.Decorations
return true;
}
- public override bool GenerateAt(IWorld world, IChunk chunk, Coordinates3D location)
+ public override bool GenerateAt(IWorldSeed world, ISpatialBlockInformationProvider chunk, Coordinates3D location)
{
if (!ValidLocation(location))
return false;
diff --git a/TrueCraft.Core/TerrainGen/Decorations/ConiferTree.cs b/TrueCraft.Core/TerrainGen/Decorations/ConiferTree.cs
index 7a7cfd3..3b7b7c5 100644
--- a/TrueCraft.Core/TerrainGen/Decorations/ConiferTree.cs
+++ b/TrueCraft.Core/TerrainGen/Decorations/ConiferTree.cs
@@ -13,7 +13,7 @@ namespace TrueCraft.Core.TerrainGen.Decorations
{
const int LeafRadius = 2;
- public override bool GenerateAt(IWorld world, IChunk chunk, Coordinates3D location)
+ public override bool GenerateAt(IWorldSeed world, ISpatialBlockInformationProvider chunk, Coordinates3D location)
{
if (!ValidLocation(location))
return false;
diff --git a/TrueCraft.Core/TerrainGen/Decorations/Decoration.cs b/TrueCraft.Core/TerrainGen/Decorations/Decoration.cs
index 325540b..625b79f 100644
--- a/TrueCraft.Core/TerrainGen/Decorations/Decoration.cs
+++ b/TrueCraft.Core/TerrainGen/Decorations/Decoration.cs
@@ -12,7 +12,7 @@ namespace TrueCraft.Core.TerrainGen.Decorations
{
public virtual bool ValidLocation(Coordinates3D location) { return true; }
- public abstract bool GenerateAt(IWorld world, IChunk chunk, Coordinates3D location);
+ public abstract bool GenerateAt(IWorldSeed world, ISpatialBlockInformationProvider chunk, Coordinates3D location);
public static bool IsCuboidWall(Coordinates2D location, Coordinates3D start, Vector3 size)
{
@@ -30,7 +30,7 @@ namespace TrueCraft.Core.TerrainGen.Decorations
|| location.X.Equals(start.X + (int)size.X - 1) && location.Z.Equals(start.Z + (int)size.Z - 1);
}
- public static bool NeighboursBlock(IChunk chunk, Coordinates3D location, byte block, byte meta = 0x0)
+ public static bool NeighboursBlock(ISpatialBlockInformationProvider chunk, Coordinates3D location, byte block, byte meta = 0x0)
{
var surrounding = new[] {
location + Coordinates3D.Left,
@@ -40,12 +40,12 @@ namespace TrueCraft.Core.TerrainGen.Decorations
};
for (int i = 0; i < surrounding.Length; i++)
{
- var toCheck = surrounding[i];
- if (toCheck.X < 0 || toCheck.X >= Chunk.Width || toCheck.Z < 0 || toCheck.Z >= Chunk.Depth || toCheck.Y < 0 || toCheck.Y >= Chunk.Height)
+ var locationToCheck = surrounding[i];
+ if (locationToCheck.X < 0 || locationToCheck.X >= Chunk.Width || locationToCheck.Z < 0 || locationToCheck.Z >= Chunk.Depth || locationToCheck.Y < 0 || locationToCheck.Y >= Chunk.Height)
return false;
- if (chunk.GetBlockID(toCheck).Equals(block))
+ if (chunk.GetBlockID(locationToCheck).Equals(block))
{
- if (meta != 0x0 && chunk.GetMetadata(toCheck) != meta)
+ if (meta != 0x0 && chunk.GetMetadata(locationToCheck) != meta)
return false;
return true;
}
@@ -53,7 +53,7 @@ namespace TrueCraft.Core.TerrainGen.Decorations
return false;
}
- public static void GenerateColumn(IChunk chunk, Coordinates3D location, int height, byte block, byte meta = 0x0)
+ public static void GenerateColumn(ISpatialBlockInformationProvider chunk, Coordinates3D location, int height, byte block, byte meta = 0x0)
{
for (int offset = 0; offset < height; offset++)
{
@@ -71,7 +71,7 @@ namespace TrueCraft.Core.TerrainGen.Decorations
* 0x1 - Hollow cuboid of the specified block
* 0x2 - Outlines the area of the cuboid using the specified block
*/
- public static void GenerateCuboid(IChunk chunk, Coordinates3D location, Vector3 size, byte block, byte meta = 0x0, byte mode = 0x0)
+ public static void GenerateCuboid(ISpatialBlockInformationProvider chunk, Coordinates3D location, Vector3 size, byte block, byte meta = 0x0, byte mode = 0x0)
{
//If mode is 0x2 offset the size by 2 and change mode to 0x1
if (mode.Equals(0x2))
@@ -102,7 +102,7 @@ namespace TrueCraft.Core.TerrainGen.Decorations
}
}
- protected void GenerateVanillaLeaves(IChunk chunk, Coordinates3D location, int radius, byte block, byte meta = 0x0)
+ protected void GenerateVanillaLeaves(ISpatialBlockInformationProvider chunk, Coordinates3D location, int radius, byte block, byte meta = 0x0)
{
int radiusOffset = radius;
for (int yOffset = -radius; yOffset <= radius; yOffset = (yOffset + 1))
@@ -116,7 +116,7 @@ namespace TrueCraft.Core.TerrainGen.Decorations
}
}
- protected void GenerateVanillaCircle(IChunk chunk, Coordinates3D location, int radius, byte block, byte meta = 0x0, double corner = 0)
+ protected void GenerateVanillaCircle(ISpatialBlockInformationProvider chunk, Coordinates3D location, int radius, byte block, byte meta = 0x0, double corner = 0)
{
for (int i = -radius; i <= radius; i = (i + 1))
{
@@ -146,7 +146,7 @@ namespace TrueCraft.Core.TerrainGen.Decorations
}
}
- protected void GenerateCircle(IChunk chunk, Coordinates3D location, int radius, byte block, byte meta = 0x0)
+ protected void GenerateCircle(ISpatialBlockInformationProvider chunk, Coordinates3D location, int radius, byte block, byte meta = 0x0)
{
for (int i = -radius; i <= radius; i = (i + 1))
{
@@ -172,7 +172,7 @@ namespace TrueCraft.Core.TerrainGen.Decorations
}
}
- protected static void GenerateSphere(IChunk chunk, Coordinates3D location, int radius, byte block, byte meta = 0x0)
+ protected static void GenerateSphere(ISpatialBlockInformationProvider chunk, Coordinates3D location, int radius, byte block, byte meta = 0x0)
{
for (int i = -radius; i <= radius; i = (i + 1))
{
diff --git a/TrueCraft.Core/TerrainGen/Decorations/Dungeon.cs b/TrueCraft.Core/TerrainGen/Decorations/Dungeon.cs
index 6edd523..6580d5b 100644
--- a/TrueCraft.Core/TerrainGen/Decorations/Dungeon.cs
+++ b/TrueCraft.Core/TerrainGen/Decorations/Dungeon.cs
@@ -26,7 +26,7 @@ namespace TrueCraft.Core.TerrainGen.Decorations
return true;
}
- public override bool GenerateAt(IWorld world, IChunk chunk, Coordinates3D location)
+ public override bool GenerateAt(IWorldSeed world, ISpatialBlockInformationProvider chunk, Coordinates3D location)
{
Console.WriteLine("Dungeon in chunk {0}", chunk.Coordinates);
if (!ValidLocation(location))
@@ -52,7 +52,7 @@ namespace TrueCraft.Core.TerrainGen.Decorations
return true;
}
- private void CreateEntraces(IChunk chunk, Coordinates3D location, Random random)
+ private void CreateEntraces(ISpatialBlockInformationProvider chunk, Coordinates3D location, Random random)
{
int entrances = 0;
var above = location + Coordinates3D.Up;
@@ -80,7 +80,7 @@ namespace TrueCraft.Core.TerrainGen.Decorations
}
}
- private void MossFloor(IChunk chunk, Coordinates3D location, Random random)
+ private void MossFloor(ISpatialBlockInformationProvider chunk, Coordinates3D location, Random random)
{
for (int x = location.X; x < location.X + Size.X; x++)
{
@@ -96,7 +96,7 @@ namespace TrueCraft.Core.TerrainGen.Decorations
}
}
- private void PlaceChests(IChunk chunk, Coordinates3D location, Random random)
+ private void PlaceChests(ISpatialBlockInformationProvider chunk, Coordinates3D location, Random random)
{
var above = location + Coordinates3D.Up;
var chests = random.Next(0, 2);
diff --git a/TrueCraft.Core/TerrainGen/Decorations/OakTree.cs b/TrueCraft.Core/TerrainGen/Decorations/OakTree.cs
index 3c17d19..6d6fd1f 100644
--- a/TrueCraft.Core/TerrainGen/Decorations/OakTree.cs
+++ b/TrueCraft.Core/TerrainGen/Decorations/OakTree.cs
@@ -23,7 +23,7 @@ namespace TrueCraft.Core.TerrainGen.Decorations
return true;
}
- public override bool GenerateAt(IWorld world, IChunk chunk, Coordinates3D location)
+ public override bool GenerateAt(IWorldSeed world, ISpatialBlockInformationProvider chunk, Coordinates3D location)
{
if (!ValidLocation(location))
return false;
diff --git a/TrueCraft.Core/TerrainGen/Decorations/PineTree.cs b/TrueCraft.Core/TerrainGen/Decorations/PineTree.cs
index be12487..3a3f6b6 100644
--- a/TrueCraft.Core/TerrainGen/Decorations/PineTree.cs
+++ b/TrueCraft.Core/TerrainGen/Decorations/PineTree.cs
@@ -23,7 +23,7 @@ namespace TrueCraft.Core.TerrainGen.Decorations
return true;
}
- public override bool GenerateAt(IWorld world, IChunk chunk, Coordinates3D location)
+ public override bool GenerateAt(IWorldSeed world, ISpatialBlockInformationProvider chunk, Coordinates3D location)
{
if (!ValidLocation(location))
return false;
@@ -51,7 +51,7 @@ namespace TrueCraft.Core.TerrainGen.Decorations
* 0x0 - two level topper
* 0x1 - three level topper
*/
- protected void GenerateTopper(IChunk chunk, Coordinates3D location, byte type = 0x0)
+ protected void GenerateTopper(ISpatialBlockInformationProvider chunk, Coordinates3D location, byte type = 0x0)
{
const int sectionRadius = 1;
GenerateCircle(chunk, location, sectionRadius, LeavesBlock.BlockID, 0x1);
diff --git a/TrueCraft.Core/TerrainGen/Decorators/CactusDecorator.cs b/TrueCraft.Core/TerrainGen/Decorators/CactusDecorator.cs
index a2b9671..a61bd54 100644
--- a/TrueCraft.Core/TerrainGen/Decorators/CactusDecorator.cs
+++ b/TrueCraft.Core/TerrainGen/Decorators/CactusDecorator.cs
@@ -7,13 +7,14 @@ using TrueCraft.Core.World;
using TrueCraft.Core.TerrainGen.Noise;
using TrueCraft.Core.Logic.Blocks;
using TrueCraft.API;
+using TrueCraft.API.Logic;
using TrueCraft.Core.TerrainGen.Decorations;
namespace TrueCraft.Core.TerrainGen.Decorators
{
public class CactusDecorator : IChunkDecorator
{
- public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes)
+ public void Decorate(IWorldSeed world, ISpatialBlockInformationProvider chunk, IBiomeRepository biomes, IBlockRepository blockRepository)
{
var noise = new Perlin(world.Seed);
var chanceNoise = new ClampNoise(noise);
diff --git a/TrueCraft.Core/TerrainGen/Decorators/DungeonDecorator.cs b/TrueCraft.Core/TerrainGen/Decorators/DungeonDecorator.cs
index 18493f2..62bec23 100644
--- a/TrueCraft.Core/TerrainGen/Decorators/DungeonDecorator.cs
+++ b/TrueCraft.Core/TerrainGen/Decorators/DungeonDecorator.cs
@@ -6,6 +6,7 @@ using TrueCraft.API.World;
using TrueCraft.Core.World;
using TrueCraft.Core.TerrainGen.Noise;
using TrueCraft.API;
+using TrueCraft.API.Logic;
using TrueCraft.Core.Logic.Blocks;
using TrueCraft.Core.TerrainGen.Decorations;
@@ -20,7 +21,7 @@ namespace TrueCraft.Core.TerrainGen.Decorators
this.BaseLevel = groundLevel;
}
- public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes)
+ public void Decorate(IWorldSeed world, ISpatialBlockInformationProvider chunk, IBiomeRepository biomes, IBlockRepository blockRepository)
{
for (int attempts = 0; attempts < 8; attempts++)
{
diff --git a/TrueCraft.Core/TerrainGen/Decorators/FreezeDecorator.cs b/TrueCraft.Core/TerrainGen/Decorators/FreezeDecorator.cs
index 1d1ea8d..4e34f92 100644
--- a/TrueCraft.Core/TerrainGen/Decorators/FreezeDecorator.cs
+++ b/TrueCraft.Core/TerrainGen/Decorators/FreezeDecorator.cs
@@ -6,12 +6,13 @@ using TrueCraft.API.World;
using TrueCraft.Core.World;
using TrueCraft.Core.Logic.Blocks;
using TrueCraft.API;
+using TrueCraft.API.Logic;
namespace TrueCraft.Core.TerrainGen.Decorators
{
class FreezeDecorator : IChunkDecorator
{
- public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes)
+ public void Decorate(IWorldSeed world, ISpatialBlockInformationProvider chunk, IBiomeRepository biomes, IBlockRepository blockRepository)
{
for (int x = 0; x < 16; x++)
{
@@ -50,7 +51,7 @@ namespace TrueCraft.Core.TerrainGen.Decorators
}
}
- bool CoverIce(IChunk chunk, IBiomeRepository biomes, Coordinates3D location)
+ bool CoverIce(ISpatialBlockInformationProvider chunk, IBiomeRepository biomes, Coordinates3D location)
{
const int maxDistance = 4;
var adjacent = new[] {
diff --git a/TrueCraft.Core/TerrainGen/Decorators/LiquidDecorator.cs b/TrueCraft.Core/TerrainGen/Decorators/LiquidDecorator.cs
index 2e4aa69..3fa02a6 100644
--- a/TrueCraft.Core/TerrainGen/Decorators/LiquidDecorator.cs
+++ b/TrueCraft.Core/TerrainGen/Decorators/LiquidDecorator.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using TrueCraft.API.World;
using TrueCraft.API;
+using TrueCraft.API.Logic;
using TrueCraft.Core.World;
using TrueCraft.Core.Logic.Blocks;
using TrueCraft.Core.TerrainGen.Noise;
@@ -14,7 +15,7 @@ namespace TrueCraft.Core.TerrainGen.Decorators
{
public static readonly int WaterLevel = 40;
- public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes)
+ public void Decorate(IWorldSeed world, ISpatialBlockInformationProvider chunk, IBiomeRepository biomes, IBlockRepository blockRepository)
{
for (int x = 0; x < Chunk.Width; x++)
{
diff --git a/TrueCraft.Core/TerrainGen/Decorators/OreDecorator.cs b/TrueCraft.Core/TerrainGen/Decorators/OreDecorator.cs
index 3f9f8d1..394cc3f 100644
--- a/TrueCraft.Core/TerrainGen/Decorators/OreDecorator.cs
+++ b/TrueCraft.Core/TerrainGen/Decorators/OreDecorator.cs
@@ -8,6 +8,7 @@ using TrueCraft.Core.World;
using TrueCraft.API;
using TrueCraft.Core.Logic.Blocks;
using System.IO;
+using TrueCraft.API.Logic;
namespace TrueCraft.Core.TerrainGen.Decorators
{
@@ -53,7 +54,7 @@ namespace TrueCraft.Core.TerrainGen.Decorators
Ores.Add(redstone);
}
- public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes)
+ public void Decorate(IWorldSeed world, ISpatialBlockInformationProvider chunk, IBiomeRepository biomes, IBlockRepository blockRepository)
{
var perlin = new Perlin(world.Seed);
perlin.Lacunarity = 1;
diff --git a/TrueCraft.Core/TerrainGen/Decorators/PlantDecorator.cs b/TrueCraft.Core/TerrainGen/Decorators/PlantDecorator.cs
index 559ef76..2c3ec8f 100644
--- a/TrueCraft.Core/TerrainGen/Decorators/PlantDecorator.cs
+++ b/TrueCraft.Core/TerrainGen/Decorators/PlantDecorator.cs
@@ -6,13 +6,14 @@ using TrueCraft.API.World;
using TrueCraft.Core.TerrainGen.Noise;
using TrueCraft.Core.World;
using TrueCraft.API;
+using TrueCraft.API.Logic;
using TrueCraft.Core.Logic.Blocks;
namespace TrueCraft.Core.TerrainGen.Decorators
{
public class PlantDecorator : IChunkDecorator
{
- public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes)
+ public void Decorate(IWorldSeed world, ISpatialBlockInformationProvider chunk, IBiomeRepository biomes, IBlockRepository blockRepository)
{
var noise = new Perlin(world.Seed);
var chanceNoise = new ClampNoise(noise);
@@ -67,23 +68,23 @@ namespace TrueCraft.Core.TerrainGen.Decorators
}
}
- void GenerateRose(IChunk chunk, Coordinates3D location)
+ void GenerateRose(ISpatialBlockInformationProvider chunk, Coordinates3D location)
{
chunk.SetBlockID(location, RoseBlock.BlockID);
}
- void GenerateDandelion(IChunk chunk, Coordinates3D location)
+ void GenerateDandelion(ISpatialBlockInformationProvider chunk, Coordinates3D location)
{
chunk.SetBlockID(location, DandelionBlock.BlockID);
}
- void GenerateTallGrass(IChunk chunk, Coordinates3D location, byte meta)
+ void GenerateTallGrass(ISpatialBlockInformationProvider chunk, Coordinates3D location, byte meta)
{
chunk.SetBlockID(location, TallGrassBlock.BlockID);
chunk.SetMetadata(location, meta);
}
- void GenerateDeadBush(IChunk chunk, Coordinates3D location)
+ void GenerateDeadBush(ISpatialBlockInformationProvider chunk, Coordinates3D location)
{
chunk.SetBlockID(location, DeadBushBlock.BlockID);
}
diff --git a/TrueCraft.Core/TerrainGen/Decorators/SugarCaneDecorator.cs b/TrueCraft.Core/TerrainGen/Decorators/SugarCaneDecorator.cs
index b3fac9d..25b97eb 100644
--- a/TrueCraft.Core/TerrainGen/Decorators/SugarCaneDecorator.cs
+++ b/TrueCraft.Core/TerrainGen/Decorators/SugarCaneDecorator.cs
@@ -6,6 +6,7 @@ using TrueCraft.API.World;
using TrueCraft.Core.World;
using TrueCraft.Core.TerrainGen.Noise;
using TrueCraft.API;
+using TrueCraft.API.Logic;
using TrueCraft.Core.Logic.Blocks;
using TrueCraft.Core.TerrainGen.Decorations;
@@ -13,16 +14,38 @@ namespace TrueCraft.Core.TerrainGen.Decorators
{
public class SugarCaneDecorator : IChunkDecorator
{
- public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes)
+ private readonly NoiseGen suppliedNoise;
+
+ public SugarCaneDecorator()
{
- var noise = new Perlin(world.Seed);
+ suppliedNoise = null;
+ }
+
+ public SugarCaneDecorator(NoiseGen suppliedNoiseSource)
+ {
+ suppliedNoise = suppliedNoiseSource;
+ }
+ public void Decorate(IWorldSeed world, ISpatialBlockInformationProvider chunk, IBiomeRepository biomes, IBlockRepository blockRepository)
+ {
+ NoiseGen noise;
+ if (suppliedNoise == null)
+ {
+ noise = new Perlin(world.Seed);
+ }
+ else
+ {
+ noise = suppliedNoise;
+ }
+ var random = new Random(world.Seed);
+
var chanceNoise = new ClampNoise(noise);
chanceNoise.MaxValue = 1;
for (int x = 0; x < 16; x++)
{
for (int z = 0; z < 16; z++)
{
- var biome = biomes.GetBiome(chunk.Biomes[x * Chunk.Width + z]);
+ var chunkBiome = chunk.Biomes[x * Chunk.Width + z];
+ var biome = biomes.GetBiome(chunkBiome);
var height = chunk.HeightMap[x * Chunk.Width + z];
var blockX = MathHelper.ChunkToBlockX(x, chunk.Coordinates.X);
var blockZ = MathHelper.ChunkToBlockZ(z, chunk.Coordinates.Z);
@@ -33,9 +56,9 @@ namespace TrueCraft.Core.TerrainGen.Decorators
var blockLocation = new Coordinates3D(x, height, z);
var sugarCaneLocation = blockLocation + Coordinates3D.Up;
var neighborsWater = Decoration.NeighboursBlock(chunk, blockLocation, WaterBlock.BlockID) || Decoration.NeighboursBlock(chunk, blockLocation, StationaryWaterBlock.BlockID);
- if (chunk.GetBlockID(blockLocation).Equals(GrassBlock.BlockID) && neighborsWater || chunk.GetBlockID(blockLocation).Equals(SandBlock.BlockID) && neighborsWater)
+ var sugarCaneCanGrowOnCurrentBlock = (chunk.GetBlockID(blockLocation).Equals(GrassBlock.BlockID) || chunk.GetBlockID(blockLocation).Equals(SandBlock.BlockID));
+ if (neighborsWater && sugarCaneCanGrowOnCurrentBlock)
{
- var random = new Random(world.Seed);
double heightChance = random.NextDouble();
int caneHeight = 3;
if (heightChance < 0.05)
diff --git a/TrueCraft.Core/TerrainGen/Decorators/TreeDecorator.cs b/TrueCraft.Core/TerrainGen/Decorators/TreeDecorator.cs
index 6ed2b35..9dfff15 100644
--- a/TrueCraft.Core/TerrainGen/Decorators/TreeDecorator.cs
+++ b/TrueCraft.Core/TerrainGen/Decorators/TreeDecorator.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using TrueCraft.API.World;
using TrueCraft.API;
+using TrueCraft.API.Logic;
using TrueCraft.Core.Logic.Blocks;
using TrueCraft.Core.TerrainGen.Noise;
using TrueCraft.Core.World;
@@ -16,7 +17,7 @@ namespace TrueCraft.Core.TerrainGen.Decorators
public Perlin Noise { get; set; }
public ClampNoise ChanceNoise { get; set; }
- public void Decorate(IWorld world, IChunk chunk, IBiomeRepository biomes)
+ public void Decorate(IWorldSeed world, ISpatialBlockInformationProvider chunk, IBiomeRepository biomes, IBlockRepository blockRepository)
{
Noise = new Perlin(world.Seed);
ChanceNoise = new ClampNoise(Noise);
@@ -38,7 +39,7 @@ namespace TrueCraft.Core.TerrainGen.Decorators
{
var location = new Coordinates3D(x, height, z);
var id = chunk.GetBlockID(location);
- var provider = world.BlockRepository.GetBlockProvider(id);
+ var provider = blockRepository.GetBlockProvider(id);
if (id == DirtBlock.BlockID || id == GrassBlock.BlockID || id == SnowfallBlock.BlockID
|| (id != StationaryWaterBlock.BlockID && id != WaterBlock.BlockID
&& id != LavaBlock.BlockID && id != StationaryLavaBlock.BlockID
diff --git a/TrueCraft.Core/TerrainGen/StandardGenerator.cs b/TrueCraft.Core/TerrainGen/StandardGenerator.cs
index 6b095c9..51dfa83 100644
--- a/TrueCraft.Core/TerrainGen/StandardGenerator.cs
+++ b/TrueCraft.Core/TerrainGen/StandardGenerator.cs
@@ -189,7 +189,7 @@ namespace TrueCraft.Core.TerrainGen
}
}
foreach (var decorator in ChunkDecorators)
- decorator.Decorate(world, chunk, Biomes);
+ decorator.Decorate(world, chunk, Biomes, world.BlockRepository);
chunk.TerrainPopulated = true;
chunk.UpdateHeightMap();
return chunk;
diff --git a/TrueCraft.Core/TrueCraft.Core.csproj b/TrueCraft.Core/TrueCraft.Core.csproj
index 246f610..2da648e 100644
--- a/TrueCraft.Core/TrueCraft.Core.csproj
+++ b/TrueCraft.Core/TrueCraft.Core.csproj
@@ -372,11 +372,7 @@
TrueCraft.Profiling
-
-
-
-
-
+