diff --git a/TrueCraft.API/TrueCraft.API.csproj b/TrueCraft.API/TrueCraft.API.csproj
index 56e7b11..35c79c0 100644
--- a/TrueCraft.API/TrueCraft.API.csproj
+++ b/TrueCraft.API/TrueCraft.API.csproj
@@ -65,6 +65,7 @@
+
diff --git a/TrueCraft.API/World/IDecoration.cs b/TrueCraft.API/World/IDecoration.cs
new file mode 100644
index 0000000..bd87e45
--- /dev/null
+++ b/TrueCraft.API/World/IDecoration.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace TrueCraft.API.World
+{
+ public interface IDecoration
+ {
+ bool ValidLocation(Coordinates3D location);
+ bool GenerateAt(IWorld world, IChunk chunk, Coordinates3D location);
+ }
+}
\ No newline at end of file
diff --git a/TrueCraft.Core/Logic/Blocks/MonsterSpawnerBlock.cs b/TrueCraft.Core/Logic/Blocks/MonsterSpawnerBlock.cs
index 6f35932..cf1906a 100644
--- a/TrueCraft.Core/Logic/Blocks/MonsterSpawnerBlock.cs
+++ b/TrueCraft.Core/Logic/Blocks/MonsterSpawnerBlock.cs
@@ -1,5 +1,6 @@
using System;
using TrueCraft.API.Logic;
+using TrueCraft.API;
namespace TrueCraft.Core.Logic.Blocks
{
@@ -23,5 +24,10 @@ namespace TrueCraft.Core.Logic.Blocks
{
return new Tuple(1, 4);
}
+
+ protected override ItemStack[] GetDrop(BlockDescriptor descriptor)
+ {
+ return new ItemStack[0];
+ }
}
}
\ No newline at end of file
diff --git a/TrueCraft.Core/TerrainGen/Decorations/BalloonOakTree.cs b/TrueCraft.Core/TerrainGen/Decorations/BalloonOakTree.cs
new file mode 100644
index 0000000..74cf8f6
--- /dev/null
+++ b/TrueCraft.Core/TerrainGen/Decorations/BalloonOakTree.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using TrueCraft.API.World;
+using TrueCraft.API;
+using TrueCraft.Core.Logic.Blocks;
+using TrueCraft.Core.World;
+
+namespace TrueCraft.Core.TerrainGen.Decorations
+{
+ public class BalloonOakTree : Decoration
+ {
+ int LeafRadius = 2;
+
+ public override bool ValidLocation(Coordinates3D location)
+ {
+ if (location.X - LeafRadius < 0 || location.X + LeafRadius >= Chunk.Width || location.Z - LeafRadius < 0 || location.Z + LeafRadius >= Chunk.Depth || location.Y + LeafRadius >= Chunk.Height)
+ return false;
+ return true;
+ }
+
+ public override bool GenerateAt(IWorld world, IChunk chunk, Coordinates3D location)
+ {
+ if (!ValidLocation(location))
+ return false;
+
+ Random R = new Random(world.Seed);
+ int Height = R.Next(4, 5);
+ GenerateColumn(chunk, location, Height, WoodBlock.BlockID, 0x0);
+ Coordinates3D LeafLocation = location + new Coordinates3D(0, Height, 0);
+ GenerateSphere(chunk, LeafLocation, LeafRadius, LeavesBlock.BlockID, 0x0);
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/TrueCraft.Core/TerrainGen/Decorations/BirchTree.cs b/TrueCraft.Core/TerrainGen/Decorations/BirchTree.cs
new file mode 100644
index 0000000..69696e6
--- /dev/null
+++ b/TrueCraft.Core/TerrainGen/Decorations/BirchTree.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using TrueCraft.API.World;
+using TrueCraft.API;
+using TrueCraft.Core.Logic.Blocks;
+using TrueCraft.Core.World;
+
+namespace TrueCraft.Core.TerrainGen.Decorations
+{
+ public class BirchTree : Decoration
+ {
+ int LeafRadius = 2;
+
+ public override bool ValidLocation(Coordinates3D location)
+ {
+ if (location.X - LeafRadius < 0 || location.X + LeafRadius >= Chunk.Width || location.Z - LeafRadius < 0 || location.Z + LeafRadius >= Chunk.Depth)
+ return false;
+ return true;
+ }
+
+ public override bool GenerateAt(IWorld world, IChunk chunk, Coordinates3D location)
+ {
+ if (!ValidLocation(location))
+ return false;
+
+ Random R = new Random(world.Seed);
+ int Height = R.Next(4, 5);
+ GenerateColumn(chunk, location, Height, WoodBlock.BlockID, 0x2);
+ Coordinates3D LeafLocation = location + new Coordinates3D(0, Height, 0);
+ GenerateVanillaLeaves(chunk, LeafLocation, LeafRadius, LeavesBlock.BlockID, 0x2);
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/TrueCraft.Core/TerrainGen/Decorations/ConiferTree.cs b/TrueCraft.Core/TerrainGen/Decorations/ConiferTree.cs
new file mode 100644
index 0000000..a8155d5
--- /dev/null
+++ b/TrueCraft.Core/TerrainGen/Decorations/ConiferTree.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using TrueCraft.API;
+using TrueCraft.API.World;
+using TrueCraft.Core.Logic.Blocks;
+using TrueCraft.Core.World;
+
+namespace TrueCraft.Core.TerrainGen.Decorations
+{
+ public class ConiferTree : PineTree
+ {
+ int LeafRadius = 2;
+ int LeafOffset = 3;
+ public override bool GenerateAt(IWorld world, IChunk chunk, Coordinates3D location)
+ {
+ if (!ValidLocation(location))
+ return false;
+
+ Random R = new Random(world.Seed);
+ int Height = R.Next(7, 8);
+ GenerateColumn(chunk, location, Height, WoodBlock.BlockID, 0x1);
+ GenerateCircle(chunk, location + new Coordinates3D(0, Height - 2, 0), LeafRadius - 1, LeavesBlock.BlockID, 0x1);
+ GenerateCircle(chunk, location + new Coordinates3D(0, Height - 1, 0), LeafRadius, LeavesBlock.BlockID, 0x1);
+ GenerateCircle(chunk, location + new Coordinates3D(0, Height, 0), LeafRadius, LeavesBlock.BlockID, 0x1);
+ GenerateTopper(chunk, (location + new Coordinates3D(0, Height + 1, 0)), 0x0);
+ return true;
+ }
+ }
+}
diff --git a/TrueCraft.Core/TerrainGen/Decorations/Decoration.cs b/TrueCraft.Core/TerrainGen/Decorations/Decoration.cs
new file mode 100644
index 0000000..55662df
--- /dev/null
+++ b/TrueCraft.Core/TerrainGen/Decorations/Decoration.cs
@@ -0,0 +1,195 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using TrueCraft.API.World;
+using TrueCraft.API;
+using TrueCraft.Core.World;
+
+namespace TrueCraft.Core.TerrainGen.Decorations
+{
+ public abstract class Decoration : IDecoration
+ {
+ public virtual bool ValidLocation(Coordinates3D location) { return true; }
+
+ public abstract bool GenerateAt(IWorld world, IChunk chunk, Coordinates3D location);
+
+ public static bool IsCuboidWall(Coordinates2D location, Coordinates3D start, Vector3 size)
+ {
+ return location.X.Equals(start.X) || location.Z.Equals(start.Z) || location.X.Equals(start.X + (int)size.X - 1) || location.Z.Equals(start.Z + (int)size.Z - 1);
+ }
+
+ public static bool IsCuboidCorner(Coordinates2D location, Coordinates3D start, Vector3 size)
+ {
+ return location.X.Equals(start.X) && location.Z.Equals(start.Z) || location.X.Equals(start.X) && location.Z.Equals(start.Z + (int)size.Z - 1) || location.X.Equals(start.X + (int)size.X - 1) && location.Z.Equals(start.Z) || 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)
+ {
+ var Surrounding = new[] {
+ location + Coordinates3D.Left,
+ location + Coordinates3D.Right,
+ location + Coordinates3D.Forwards,
+ location + Coordinates3D.Backwards,
+ };
+ for (int I = 0; I < Surrounding.Length; I++)
+ {
+ Coordinates3D Check = Surrounding[I];
+ if (Check.X < 0 || Check.X >= Chunk.Width || Check.Z < 0 || Check.Z >= Chunk.Depth || Check.Y < 0 || Check.Y >= Chunk.Height)
+ return false;
+ if (chunk.GetBlockID(Check).Equals(block))
+ {
+ if (meta != 0x0 && chunk.GetMetadata(Check) != meta)
+ return false;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static void GenerateColumn(IChunk chunk, Coordinates3D location, int height, byte block, byte meta = 0x0)
+ {
+ for (int offset = 0; offset < height; offset++)
+ {
+ Coordinates3D blockLocation = location + new Coordinates3D(0, offset, 0);
+ if (blockLocation.Y >= Chunk.Height)
+ return;
+ chunk.SetBlockID(blockLocation, block);
+ chunk.SetMetadata(blockLocation, meta);
+ }
+ }
+
+ /*
+ * Cuboid Modes
+ * 0x0 - Solid cuboid of the specified block
+ * 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)
+ {
+ //If mode is 0x2 offset the size by 2 and change mode to 0x1
+ if (mode.Equals(0x2))
+ {
+ size += new Vector3(2, 2, 2);
+ mode = 0x1;
+ }
+
+ for (int W = location.X; W < location.X + size.X; W++)
+ {
+ for (int L = location.Z; L < location.Z + size.Z; L++)
+ {
+ for (int H = location.Y; H < location.Y + size.Y; H++)
+ {
+
+ if (W < 0 || W >= Chunk.Width || L < 0 || L >= Chunk.Depth || H < 0 || H >= Chunk.Height)
+ continue;
+ Coordinates3D BlockLocation = new Coordinates3D(W, H, L);
+ if (!H.Equals(location.Y) && !H.Equals(location.Y + (int)size.Y - 1) && !IsCuboidWall(new Coordinates2D(W, L), location, size) && !IsCuboidCorner(new Coordinates2D(W, L), location, size))
+ continue;
+
+ chunk.SetBlockID(BlockLocation, block);
+ if (meta != 0x0)
+ chunk.SetMetadata(BlockLocation, meta);
+ }
+ }
+ }
+ }
+
+ protected void GenerateVanillaLeaves(IChunk chunk, Coordinates3D location, int radius, byte block, byte meta = 0x0)
+ {
+ int RadiusOffset = radius;
+ for (int YOffset = -radius; YOffset <= radius; YOffset = (YOffset + 1))
+ {
+ int Y = location.Y + YOffset;
+ if (Y > Chunk.Height)
+ continue;
+ GenerateVanillaCircle(chunk, new Coordinates3D(location.X, Y, location.Z), RadiusOffset, block, meta);
+ if (YOffset != -radius && YOffset % 2 == 0)
+ RadiusOffset--;
+ }
+ }
+
+ protected void GenerateVanillaCircle(IChunk chunk, Coordinates3D location, int radius, byte block, byte meta = 0x0, double corner = 0)
+ {
+ for (int I = -radius; I <= radius; I = (I + 1))
+ {
+ for (int J = -radius; J <= radius; J = (J + 1))
+ {
+ int Max = (int)Math.Sqrt((I * I) + (J * J));
+ if (Max <= radius)
+ {
+ if (I.Equals(-radius) && J.Equals(-radius) || I.Equals(-radius) && J.Equals(radius) || I.Equals(radius) && J.Equals(-radius) || I.Equals(radius) && J.Equals(radius))
+ {
+ if (corner + radius * 0.2 < 0.4 || corner + radius * 0.2 > 0.7 || corner.Equals(0))
+ continue;
+ }
+ int X = location.X + I;
+ int Z = location.Z + J;
+ Coordinates3D CurrentBlock = new Coordinates3D(X, location.Y, Z);
+ if (chunk.GetBlockID(CurrentBlock).Equals(0))
+ {
+ chunk.SetBlockID(CurrentBlock, block);
+ chunk.SetMetadata(CurrentBlock, meta);
+ }
+ }
+ }
+ }
+ }
+
+ protected void GenerateCircle(IChunk chunk, Coordinates3D location, int radius, byte block, byte meta = 0x0)
+ {
+ for (int I = -radius; I <= radius; I = (I + 1))
+ {
+ for (int J = -radius; J <= radius; J = (J + 1))
+ {
+ int Max = (int)Math.Sqrt((I * I) + (J * J));
+ if (Max <= radius)
+ {
+ int X = location.X + I;
+ int Z = location.Z + J;
+
+ if (X < 0 || X >= Chunk.Width || Z < 0 || Z >= Chunk.Depth)
+ continue;
+
+ Coordinates3D CurrentBlock = new Coordinates3D(X, location.Y, Z);
+ if (chunk.GetBlockID(CurrentBlock).Equals(0))
+ {
+ chunk.SetBlockID(CurrentBlock, block);
+ chunk.SetMetadata(CurrentBlock, meta);
+ }
+ }
+ }
+ }
+ }
+
+ protected static void GenerateSphere(IChunk chunk, Coordinates3D location, int radius, byte block, byte meta = 0x0)
+ {
+ for (int I = -radius; I <= radius; I = (I + 1))
+ {
+ for (int J = -radius; J <= radius; J = (J + 1))
+ {
+ for (int K = -radius; K <= radius; K = (K + 1))
+ {
+ int Max = (int)Math.Sqrt((I * I) + (J * J) + (K * K));
+ if (Max <= radius)
+ {
+ int X = location.X + I;
+ int Y = location.Y + K;
+ int Z = location.Z + J;
+
+ if (X < 0 || X >= Chunk.Width || Z < 0 || Z >= Chunk.Depth || Y < 0 || Y >= Chunk.Height)
+ continue;
+
+ Coordinates3D CurrentBlock = new Coordinates3D(X, Y, Z);
+ if (chunk.GetBlockID(CurrentBlock).Equals(0))
+ {
+ chunk.SetBlockID(CurrentBlock, block);
+ chunk.SetMetadata(CurrentBlock, meta);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/TrueCraft.Core/TerrainGen/Decorations/Dungeon.cs b/TrueCraft.Core/TerrainGen/Decorations/Dungeon.cs
new file mode 100644
index 0000000..6bfa3a6
--- /dev/null
+++ b/TrueCraft.Core/TerrainGen/Decorations/Dungeon.cs
@@ -0,0 +1,105 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using TrueCraft.API;
+using TrueCraft.API.World;
+using TrueCraft.Core.Logic.Blocks;
+using TrueCraft.Core.World;
+using TrueCraft.Core.TerrainGen.Noise;
+
+namespace TrueCraft.Core.TerrainGen.Decorations
+{
+ public class Dungeon : Decoration
+ {
+ Vector3 Size = new Vector3(7, 5, 7);
+ int MaxEntrances = 5;
+
+ public override bool ValidLocation(Coordinates3D location)
+ {
+ var OffsetSize = Size + new Vector3(1, 1, 1);
+ if (location.X + (int)OffsetSize.X >= Chunk.Width || location.Z + (int)OffsetSize.Z >= Chunk.Depth || location.Y + (int)OffsetSize.Y >= Chunk.Height)
+ return false;
+ return true;
+ }
+
+ public override bool GenerateAt(IWorld world, IChunk chunk, Coordinates3D location)
+ {
+ if (!ValidLocation(location))
+ return false;
+ Random R = new Random(world.Seed);
+
+ //Generate room
+ GenerateCuboid(chunk, location, Size, CobblestoneBlock.BlockID, 0x0, 0x2);
+
+ //Randomly add mossy cobblestone to floor
+ MossFloor(chunk, location, R);
+
+ //Place Spawner
+ chunk.SetBlockID(new Coordinates3D((int)(location.X + ((Size.X + 1) / 2)), (int)((location + Coordinates3D.Up).Y), (int)(location.Z + ((Size.Z + 1) / 2))), MonsterSpawnerBlock.BlockID);
+
+ //Create entrances
+ CreateEntraces(chunk, location, R);
+
+ //Place Chests
+ PlaceChests(chunk, location, R);
+ return true;
+ }
+
+ private void CreateEntraces(IChunk chunk, Coordinates3D location, Random R)
+ {
+ int Entrances = 0;
+ var Above = location + Coordinates3D.Up;
+ for (int X = location.X; X < location.X + Size.X; X++)
+ {
+ if (Entrances >= MaxEntrances)
+ break;
+ for (int Z = location.Z; Z < location.Z + Size.Z; Z++)
+ {
+ if (Entrances >= MaxEntrances)
+ break;
+ if (R.Next(0, 3) == 0 && IsCuboidWall(new Coordinates2D(X, Z), location, Size) && !IsCuboidCorner(new Coordinates2D(X, Z), location, Size))
+ {
+ var BlockLocation = new Coordinates3D(X, Above.Y, Z);
+ chunk.SetBlockID(BlockLocation, AirBlock.BlockID);
+ chunk.SetBlockID(BlockLocation + Coordinates3D.Up, AirBlock.BlockID);
+ }
+ }
+ }
+ }
+
+ private void MossFloor(IChunk chunk, Coordinates3D location, Random R)
+ {
+ for (int X = location.X; X < location.X + Size.X; X++)
+ {
+ for (int Z = location.Z; Z < location.Z + Size.Z; Z++)
+ {
+ if (R.Next(0, 3) == 0)
+ chunk.SetBlockID(new Coordinates3D(X, location.Y, Z), MossStoneBlock.BlockID);
+ }
+ }
+ }
+
+ private void PlaceChests(IChunk chunk, Coordinates3D location, Random R)
+ {
+ var Above = location + Coordinates3D.Up;
+ var chests = R.Next(0, 2);
+ for (int I = 0; I < chests; I++)
+ {
+ for (int Attempts = 0; Attempts < 10; Attempts++)
+ {
+ var X = R.Next(location.X, location.X + (int)Size.X);
+ var Z = R.Next(location.Z, location.Z + (int)Size.Z);
+ if (!IsCuboidWall(new Coordinates2D(X, Z), location, Size) && !IsCuboidCorner(new Coordinates2D(X, Z), location, Size))
+ {
+ if (NeighboursBlock(chunk, new Coordinates3D(X, Above.Y, Z), CobblestoneBlock.BlockID))
+ {
+ chunk.SetBlockID(new Coordinates3D(X, Above.Y, Z), ChestBlock.BlockID);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/TrueCraft.Core/TerrainGen/Decorations/OakTree.cs b/TrueCraft.Core/TerrainGen/Decorations/OakTree.cs
new file mode 100644
index 0000000..010d66b
--- /dev/null
+++ b/TrueCraft.Core/TerrainGen/Decorations/OakTree.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using TrueCraft.API;
+using TrueCraft.API.World;
+using TrueCraft.Core.Logic.Blocks;
+using TrueCraft.Core.World;
+
+namespace TrueCraft.Core.TerrainGen.Decorations
+{
+ public class OakTree : Decoration
+ {
+ int LeafRadius = 2;
+
+ public override bool ValidLocation(Coordinates3D location)
+ {
+ if (location.X - LeafRadius < 0 || location.X + LeafRadius >= Chunk.Width || location.Z - LeafRadius < 0 || location.Z + LeafRadius >= Chunk.Depth)
+ return false;
+ return true;
+ }
+
+ public override bool GenerateAt(IWorld world, IChunk chunk, Coordinates3D location)
+ {
+ if (!ValidLocation(location))
+ return false;
+
+ Random R = new Random(world.Seed);
+ int Height = R.Next(4, 5);
+ GenerateColumn(chunk, location, Height, WoodBlock.BlockID, 0x0);
+ Coordinates3D LeafLocation = location + new Coordinates3D(0, Height, 0);
+ GenerateVanillaLeaves(chunk, LeafLocation, LeafRadius, LeavesBlock.BlockID, 0x0);
+ return true;
+ }
+ }
+}
diff --git a/TrueCraft.Core/TerrainGen/Decorations/PineTree.cs b/TrueCraft.Core/TerrainGen/Decorations/PineTree.cs
new file mode 100644
index 0000000..c41d87d
--- /dev/null
+++ b/TrueCraft.Core/TerrainGen/Decorations/PineTree.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using TrueCraft.API;
+using TrueCraft.API.World;
+using TrueCraft.Core.Logic.Blocks;
+using TrueCraft.Core.World;
+
+namespace TrueCraft.Core.TerrainGen.Decorations
+{
+ public class PineTree : Decoration
+ {
+ int LeafRadius = 2;
+ int BottomSpace = 2;
+
+ public override bool ValidLocation(Coordinates3D location)
+ {
+ if (location.X - LeafRadius < 0 || location.X + LeafRadius >= Chunk.Width || location.Z - LeafRadius < 0 || location.Z + LeafRadius >= Chunk.Depth)
+ return false;
+ return true;
+ }
+
+ public override bool GenerateAt(IWorld world, IChunk chunk, Coordinates3D location)
+ {
+ if (!ValidLocation(location))
+ return false;
+
+ Random R = new Random(world.Seed);
+ int Height = R.Next(7, 8);
+ GenerateColumn(chunk, location, Height, WoodBlock.BlockID, 0x1);
+ for (int Y = 1; Y < Height; Y++)
+ {
+ if (Y % 2 == 0)
+ {
+ GenerateVanillaCircle(chunk, location + new Coordinates3D(0, Y + 1, 0), LeafRadius - 1, LeavesBlock.BlockID, 0x1);
+ continue;
+ }
+ GenerateVanillaCircle(chunk, location + new Coordinates3D(0, Y + 1, 0), LeafRadius, LeavesBlock.BlockID, 0x1);
+ }
+
+ GenerateTopper(chunk, location + new Coordinates3D(0, Height, 0), 0x1);
+ return true;
+ }
+
+ /*
+ * Generates the top of the pine/conifer trees.
+ * Type:
+ * 0x0 - two level topper
+ * 0x1 - three level topper
+ */
+ protected void GenerateTopper(IChunk chunk, Coordinates3D location, byte type = 0x0)
+ {
+ int SectionRadius = 1;
+ GenerateCircle(chunk, location, SectionRadius, LeavesBlock.BlockID, 0x1);
+ Coordinates3D top = location + Coordinates3D.Up;
+ chunk.SetBlockID(top, LeavesBlock.BlockID);
+ chunk.SetMetadata(top, 0x1);
+ if (type == 0x1 && (top + Coordinates3D.Up).Y < Chunk.Height)
+ GenerateVanillaCircle(chunk, top + Coordinates3D.Up, SectionRadius, LeavesBlock.BlockID, 0x1);
+ }
+ }
+}
\ No newline at end of file
diff --git a/TrueCraft.Core/TerrainGen/Decorators/CactusDecorator.cs b/TrueCraft.Core/TerrainGen/Decorators/CactusDecorator.cs
index 26c6b27..a37d65c 100644
--- a/TrueCraft.Core/TerrainGen/Decorators/CactusDecorator.cs
+++ b/TrueCraft.Core/TerrainGen/Decorators/CactusDecorator.cs
@@ -7,6 +7,7 @@ using TrueCraft.Core.World;
using TrueCraft.Core.TerrainGen.Noise;
using TrueCraft.Core.Logic.Blocks;
using TrueCraft.API;
+using TrueCraft.Core.TerrainGen.Decorations;
namespace TrueCraft.Core.TerrainGen.Decorators
{
@@ -34,10 +35,7 @@ namespace TrueCraft.Core.TerrainGen.Decorators
{
var HeightChance = ChanceNoise.Value2D(BlockX, BlockZ);
var CactusHeight = (HeightChance < 1.4) ? 2 : 3;
- for (int Y = CactiPosition.Y; Y < CactiPosition.Y + CactusHeight; Y++)
- {
- chunk.SetBlockID(new Coordinates3D(CactiPosition.X, Y, CactiPosition.Z), CactusBlock.BlockID);
- }
+ Decoration.GenerateColumn(chunk, CactiPosition, CactusHeight, CactusBlock.BlockID);
}
}
}
diff --git a/TrueCraft.Core/TerrainGen/Decorators/DungeonDecorator.cs b/TrueCraft.Core/TerrainGen/Decorators/DungeonDecorator.cs
index 0a4cec9..6dab83a 100644
--- a/TrueCraft.Core/TerrainGen/Decorators/DungeonDecorator.cs
+++ b/TrueCraft.Core/TerrainGen/Decorators/DungeonDecorator.cs
@@ -7,6 +7,7 @@ using TrueCraft.Core.World;
using TrueCraft.Core.TerrainGen.Noise;
using TrueCraft.API;
using TrueCraft.Core.Logic.Blocks;
+using TrueCraft.Core.TerrainGen.Decorations;
namespace TrueCraft.Core.TerrainGen.Decorators
{
@@ -32,122 +33,18 @@ namespace TrueCraft.Core.TerrainGen.Decorators
Offset += OffsetNoise.Value2D(X, Z);
int FinalX = (int)Math.Floor(X + Offset);
int FinalZ = (int)Math.Floor(Z + Offset);
- IBiomeProvider Biome = biomes.GetBiome(chunk.Biomes[X * Chunk.Width + Z]);
var Y = (int)(10 + Offset);
- if (FinalX < 6 && FinalZ < 6 && Y < BaseLevel - 10)
+
+ var BlockX = MathHelper.ChunkToBlockX(FinalX, chunk.Coordinates.X);
+ var BlockZ = MathHelper.ChunkToBlockZ(FinalZ, chunk.Coordinates.Z);
+ var SpawnValue = OffsetNoise.Value2D(BlockX, BlockZ);
+ if (SpawnValue > 1.95 && SpawnValue < 2.09)
{
- var BlockX = MathHelper.ChunkToBlockX(X, chunk.Coordinates.X);
- var BlockZ = MathHelper.ChunkToBlockZ(Z, chunk.Coordinates.Z);
- var SpawnValue = OffsetNoise.Value2D(BlockX, BlockZ);
- if (SpawnValue > 1.95 && SpawnValue < 2.09)
- {
- GenerateDungeon(world, chunk, new Coordinates3D(FinalX, Y, FinalZ), new Vector3(7, 5, 7), 2);
+ var Generated = new Dungeon().GenerateAt(world, chunk, new Coordinates3D(BlockX, Y, BlockZ));
+ if (Generated)
break;
- }
}
}
}
-
- void GenerateDungeon(IWorld world, IChunk chunk, Coordinates3D Corner, Vector3 Size, int Chests = 2)
- {
- Perlin Noise = new Perlin();
- Noise.Seed = world.Seed - (chunk.Coordinates.X + chunk.Coordinates.Z);
- int Openings = 0;
- for (int X = Corner.X; X <= Corner.X + Size.X + 1; X++)
- {
- for (int Z = Corner.Z; Z <= Corner.Z + Size.Z + 1; Z++)
- {
- for (int Y = Corner.Y; Y <= Corner.Y + Size.Y + 1; Y++)
- {
- if (Y.Equals(Corner.Y))
- {
- if (!IsWall(new Coordinates2D(X, Z), Corner, Size) && !IsCorner(new Coordinates2D(X, Z), Corner, Size))
- {
- if (Noise.Value2D(X, Z) > 0.2)
- {
- chunk.SetBlockID(new Coordinates3D(X, Y, Z), MossStoneBlock.BlockID);
- }
- else
- {
- chunk.SetBlockID(new Coordinates3D(X, Y, Z), CobblestoneBlock.BlockID);
- }
-
- }
- else
- {
- chunk.SetBlockID(new Coordinates3D(X, Y, Z), CobblestoneBlock.BlockID);
- }
- }
- else if (Y.Equals((int)(Corner.Y + Size.Y + 1)))
- {
- chunk.SetBlockID(new Coordinates3D(X, Y, Z), CobblestoneBlock.BlockID);
- }
- else
- {
- if (IsWall(new Coordinates2D(X, Z), Corner, Size))
- {
- if (Noise.Value2D(X, Z) > 0.5 && Openings < 5 && Y.Equals(Corner.Y + 1) && !IsCorner(new Coordinates2D(X, Z), Corner, Size))
- {
- Openings++;
- }
- else
- {
- if (!chunk.GetBlockID(new Coordinates3D(X, Y - 1, Z)).Equals(0) && Y <= Corner.Y + 2 || Y > Corner.Y + 2)
- {
- chunk.SetBlockID(new Coordinates3D(X, Y, Z), CobblestoneBlock.BlockID);
- }
- }
- }
- }
- }
- }
- }
- chunk.SetBlockID(new Coordinates3D((int)(Corner.X + ((Size.X + 1) / 2)), (int)(Corner.Y + 1), (int)(Corner.Z + ((Size.Z + 1) / 2))), MonsterSpawnerBlock.BlockID);
- PlaceChests(Noise, chunk, Corner, Size, Chests);
- }
-
- void PlaceChests(Perlin DungeonNoise, IChunk chunk, Coordinates3D Corner, Vector3 Size, int Chests)
- {
- ClampNoise ChestNoise = new ClampNoise(DungeonNoise);
- for (int I = 0; I < Chests; I++)
- {
- var X = Corner.X;
- var Z = Corner.Z;
- double Offset = 0;
- for (int Attempts = 0; Attempts < 3; Attempts++)
- {
- Offset += ChestNoise.Value2D(X, Z);
- int ChestX = (int)Math.Floor(X + Offset);
- int ChestZ = (int)Math.Floor(Z + Offset);
- if (!IsWall(new Coordinates2D(ChestX, ChestZ), Corner, Size))
- {
- if (NeighboursBlock(chunk, new Coordinates3D(ChestX, Corner.Y + 1, ChestZ), CobblestoneBlock.BlockID))
- {
- chunk.SetBlockID(new Coordinates3D(ChestX, Corner.Y + 1, ChestZ), ChestBlock.BlockID);
- break;
- }
- }
- }
- }
- }
-
- bool NeighboursBlock(IChunk chunk, Coordinates3D Location, byte Block)
- {
- Coordinates3D Left = new Coordinates3D(Location.X - 1, Location.Y, Location.Z);
- Coordinates3D Right = new Coordinates3D(Location.X + 1, Location.Y, Location.Z);
- Coordinates3D Front = new Coordinates3D(Location.X, Location.Y, Location.Z - 1);
- Coordinates3D Back = new Coordinates3D(Location.X, Location.Y, Location.Z + 1);
- return chunk.GetBlockID(Left).Equals(Block) || chunk.GetBlockID(Right).Equals(Block) || chunk.GetBlockID(Front).Equals(Block) || chunk.GetBlockID(Back).Equals(Block);
- }
-
- bool IsWall(Coordinates2D Location, Coordinates3D Start, Vector3 Size)
- {
- return Location.X.Equals(Start.X) || Location.Z.Equals(Start.Z) || Location.X.Equals((int)(Start.X + Size.X + 1)) || Location.Z.Equals((int)(Start.Z + Size.Z + 1));
- }
-
- bool IsCorner(Coordinates2D Location, Coordinates3D Start, Vector3 Size)
- {
- return Location.X.Equals(Start.X - 1) && Location.Z.Equals(Start.Z - 1) || Location.X.Equals((int)(Start.X + Size.X + 1)) && Location.Z.Equals(Start.Z - 1) || Location.Z.Equals(Start.Z - 1) && Location.Z.Equals((int)(Start.Z + Size.Z + 1)) || Location.X.Equals((int)(Start.X + Size.X + 1)) && Location.Z.Equals((int)(Start.Z + Size.Z + 1));
- }
}
}
\ No newline at end of file
diff --git a/TrueCraft.Core/TerrainGen/Decorators/SugarCaneDecorator.cs b/TrueCraft.Core/TerrainGen/Decorators/SugarCaneDecorator.cs
index 0d3dde3..9e93a0e 100644
--- a/TrueCraft.Core/TerrainGen/Decorators/SugarCaneDecorator.cs
+++ b/TrueCraft.Core/TerrainGen/Decorators/SugarCaneDecorator.cs
@@ -7,6 +7,7 @@ using TrueCraft.Core.World;
using TrueCraft.Core.TerrainGen.Noise;
using TrueCraft.API;
using TrueCraft.Core.Logic.Blocks;
+using TrueCraft.Core.TerrainGen.Decorations;
namespace TrueCraft.Core.TerrainGen.Decorators
{
@@ -31,55 +32,23 @@ namespace TrueCraft.Core.TerrainGen.Decorators
if (Noise.Value2D(BlockX, BlockZ) > 0.65)
{
Coordinates3D BlockLocation = new Coordinates3D(X, Height, Z);
- Coordinates3D StalkStart = BlockLocation + Coordinates3D.Up;
- if (chunk.GetBlockID(BlockLocation).Equals(GrassBlock.BlockID) && NeighboursWater(chunk, BlockLocation) || chunk.GetBlockID(BlockLocation).Equals(SandBlock.BlockID) && NeighboursWater(chunk, BlockLocation))
+ Coordinates3D SugarCaneLocation = BlockLocation + Coordinates3D.Up;
+ var NeighboursWater = Decoration.NeighboursBlock(chunk, BlockLocation, WaterBlock.BlockID) || Decoration.NeighboursBlock(chunk, BlockLocation, StationaryWaterBlock.BlockID);
+ if (chunk.GetBlockID(BlockLocation).Equals(GrassBlock.BlockID) && NeighboursWater || chunk.GetBlockID(BlockLocation).Equals(SandBlock.BlockID) && NeighboursWater)
{
- PlaceStalk(chunk, StalkStart, world.Seed);
+ Random R = new Random(world.Seed);
+ double HeightChance = R.NextDouble();
+ int CaneHeight = 3;
+ if (HeightChance < 0.05)
+ CaneHeight = 4;
+ else if (HeightChance > 0.1 && Height < 0.25)
+ CaneHeight = 2;
+ Decoration.GenerateColumn(chunk, SugarCaneLocation, CaneHeight, SugarcaneBlock.BlockID);
}
}
}
}
}
}
-
- void PlaceStalk(IChunk chunk, Coordinates3D location, int seed)
- {
- Random R = new Random(seed);
- double HeightChance = R.NextDouble();
- int Height = 3;
- if (HeightChance < 0.05)
- {
- Height = 4;
- }
- else if (HeightChance > 0.1 && Height < 0.25)
- {
- Height = 2;
- }
- Coordinates3D NewLocation = location;
- for (int Y = location.Y; Y < location.Y + Height; Y++)
- {
- NewLocation.Y = Y;
- chunk.SetBlockID(NewLocation, SugarcaneBlock.BlockID);
- }
- }
-
- bool NeighboursWater(IChunk chunk, Coordinates3D location)
- {
- var Surrounding = new[] {
- location + Coordinates3D.Left,
- location + Coordinates3D.Right,
- location + Coordinates3D.Forwards,
- location + Coordinates3D.Backwards,
- };
- for (int I = 0; I < Surrounding.Length; I++)
- {
- Coordinates3D Check = Surrounding[I];
- if (Check.X < 0 || Check.X >= Chunk.Width || Check.Z < 0 || Check.Z >= Chunk.Depth || Check.Y < 0 || Check.Y >= Chunk.Height)
- return false;
- if (chunk.GetBlockID(Check).Equals(WaterBlock.BlockID) || chunk.GetBlockID(Check).Equals(StationaryWaterBlock.BlockID))
- return true;
- }
- return false;
- }
}
}
\ No newline at end of file
diff --git a/TrueCraft.Core/TerrainGen/Decorators/TreeDecorator.cs b/TrueCraft.Core/TerrainGen/Decorators/TreeDecorator.cs
index b86ee96..fa5c285 100644
--- a/TrueCraft.Core/TerrainGen/Decorators/TreeDecorator.cs
+++ b/TrueCraft.Core/TerrainGen/Decorators/TreeDecorator.cs
@@ -7,6 +7,7 @@ using TrueCraft.API;
using TrueCraft.Core.Logic.Blocks;
using TrueCraft.Core.TerrainGen.Noise;
using TrueCraft.Core.World;
+using TrueCraft.Core.TerrainGen.Decorations;
namespace TrueCraft.Core.TerrainGen.Decorators
{
@@ -28,7 +29,7 @@ namespace TrueCraft.Core.TerrainGen.Decorators
IBiomeProvider Biome = biomes.GetBiome(chunk.Biomes[X * Chunk.Width + Z]);
var BlockX = MathHelper.ChunkToBlockX(X, chunk.Coordinates.X);
var BlockZ = MathHelper.ChunkToBlockZ(Z, chunk.Coordinates.Z);
- var Height = chunk.HeightMap[X * Chunk.Width + Z] + 1;
+ var Height = chunk.HeightMap[X * Chunk.Width + Z];
if (!LastTree.Equals(null) && LastTree.DistanceTo(new Coordinates2D(X, Z)) < Biome.TreeDensity)
{
@@ -37,215 +38,52 @@ namespace TrueCraft.Core.TerrainGen.Decorators
if (Noise.Value2D(BlockX, BlockZ) > 0.3)
{
- if (chunk.GetBlockID(new Coordinates3D(X, Height - 1, Z)).Equals(GrassBlock.BlockID))
+ Coordinates3D location = new Coordinates3D(X, Height, Z);
+ if (chunk.GetBlockID(location).Equals(GrassBlock.BlockID))
{
var Chance = ChanceNoise.Value2D(BlockX, BlockZ);
var OakNoise = ChanceNoise.Value2D(BlockX * 0.6, BlockZ * 0.6);
var BirchNoise = ChanceNoise.Value2D(BlockX * 0.2, BlockZ * 0.2);
var SpruceNoise = ChanceNoise.Value2D(BlockX * 0.35, BlockZ * 0.35);
- //We currently have to limit where trees can spawn in the trunk due to not being able to use other chunks during generation.
- if (X + 4 > 15 || Z + 4 > 15 || X - 4 < 0 || Z - 4 < 0)
- continue;
+
+ Coordinates3D Base = location + Coordinates3D.Up;
if (Biome.Trees.Contains(TreeSpecies.Oak) && OakNoise > 1.01 && OakNoise < 1.25)
{
- GenerateTree(chunk, new Coordinates3D(X, Height, Z), TreeSpecies.Oak);
- LastTree = new Coordinates2D(X, Z);
- continue;
+ var Oak = new OakTree().GenerateAt(world, chunk, Base);
+ if (Oak)
+ {
+ LastTree = new Coordinates2D(X, Z);
+ continue;
+ }
}
if (Biome.Trees.Contains(TreeSpecies.Birch) && BirchNoise > 0.3 && BirchNoise < 0.95)
{
- GenerateTree(chunk, new Coordinates3D(X, Height, Z), TreeSpecies.Birch);
- LastTree = new Coordinates2D(X, Z);
- continue;
+ var Birch = new BirchTree().GenerateAt(world, chunk, Base);
+ if (Birch)
+ {
+ LastTree = new Coordinates2D(X, Z);
+ continue;
+ }
}
if (Biome.Trees.Contains(TreeSpecies.Spruce) && SpruceNoise < 0.75)
{
- if (X + 3 > 15 || Z + 3 > 15 || X - 3 < 0 || Z - 3 < 0)
+ Random R = new Random(world.Seed);
+ var type = R.Next(1, 2);
+ var Generated = false;
+ if (type.Equals(1))
+ {
+ Generated = new PineTree().GenerateAt(world, chunk, Base);
+ }
+ else
+ {
+ Generated = new ConiferTree().GenerateAt(world, chunk, Base);
+ }
+
+ if (Generated)
+ {
+ LastTree = new Coordinates2D(X, Z);
continue;
- GenerateTree(chunk, new Coordinates3D(X, Height, Z), TreeSpecies.Spruce);
- LastTree = new Coordinates2D(X, Z);
- continue;
- }
- }
- }
- }
- }
- }
-
- private void GenerateTree(IChunk chunk, Coordinates3D Base, TreeSpecies TreeType)
- {
- switch (TreeType)
- {
- case TreeSpecies.Oak:
- GenerateOak(chunk, Base, 0x0, 0x0);
- break;
- case TreeSpecies.Birch:
- GenerateOak(chunk, Base, 0x2, 0x2);
- break;
- case TreeSpecies.Spruce:
- GenerateSpruce(chunk, Base, 0x1, 0x1);
- break;
- default:
- GenerateOak(chunk, Base, 0x0, 0x0);
- break;
- }
- }
-
- private void GenerateOak(IChunk chunk, Coordinates3D Base, byte Logs, byte Leaves, OakType Type = OakType.Normal)
- {
- var BlockX = MathHelper.ChunkToBlockX(Base.X, chunk.Coordinates.X);
- var BlockZ = MathHelper.ChunkToBlockZ(Base.Z, chunk.Coordinates.Z);
- var HeightChance = ChanceNoise.Value2D(BlockX, BlockZ);
- var TreeHeight = (HeightChance < 1.2) ? 4 : 5;
- int Radius = 2;
- if (Type.Equals(OakType.Normal))
- {
- int OffRadius = Radius;
- int Offset = 1;
- for (int Y = Base.Y; Y < Base.Y + TreeHeight + 2; Y++)
- {
- if (Y - Base.Y <= TreeHeight)
- {
- chunk.SetBlockID(new Coordinates3D(Base.X, Y, Base.Z), WoodBlock.BlockID);
- chunk.SetMetadata(new Coordinates3D(Base.X, Y, Base.Z), Logs);
- }
- if (Y - Base.Y >= TreeHeight - Radius)
- {
- GenerateCircleLeaves(chunk, new Coordinates3D(Base.X, Y, Base.Z), OffRadius, Leaves, ChanceNoise.Value2D((BlockX / Y) * 0.25, (BlockZ / Y) * 0.25));
- if (Offset % 2 == 0)
- OffRadius--;
- Offset++;
- }
- }
- }
- else if (Type.Equals(OakType.BalloonBlocky))
- {
- int OffRadius = 1;//Start at 1
- int Offset = 1;
- for (int Y = Base.Y; Y < Base.Y + TreeHeight + 3; Y++)
- {
- if (Y - Base.Y <= TreeHeight)
- {
- chunk.SetBlockID(new Coordinates3D(Base.X, Y, Base.Z), WoodBlock.BlockID);
- chunk.SetMetadata(new Coordinates3D(Base.X, Y, Base.Z), Logs);
- }
- if (Y - Base.Y >= TreeHeight - Radius)
- {
- GenerateCircleLeaves(chunk, new Coordinates3D(Base.X, Y, Base.Z), OffRadius, Leaves);
- if ((Offset - 1) % 3 == 0 && OffRadius.Equals(2) || Offset % 1 == 0 && OffRadius.Equals(1))
- {
- if (Y - Base.Y >= TreeHeight)
- {
- OffRadius--;
- }
- else
- {
- OffRadius++;
- }
- }
- Offset++;
- }
- }
- }
- else if (Type.Equals(OakType.Balloon))
- {
- for (int Y = Base.Y; Y < Base.Y + TreeHeight; Y++)
- {
- if (Y - Base.Y <= TreeHeight)
- {
- chunk.SetBlockID(new Coordinates3D(Base.X, Y, Base.Z), WoodBlock.BlockID);
- chunk.SetMetadata(new Coordinates3D(Base.X, Y, Base.Z), Logs);
- }
- GenerateSphereLeaves(chunk, new Coordinates3D(Base.X, Base.Y + TreeHeight, Base.Z), Radius, Leaves);
- }
- }
- //TODO: I don't want to implement branched oak trees until we're able to use other chunks during generation
- }
-
- private void GenerateSpruce(IChunk chunk, Coordinates3D Base, byte Logs, byte Leaves)
- {
- var BlockX = MathHelper.ChunkToBlockX(Base.X, chunk.Coordinates.X);
- var BlockZ = MathHelper.ChunkToBlockZ(Base.Z, chunk.Coordinates.Z);
- var HeightChance = ChanceNoise.Value2D(BlockX, BlockZ);
- var TreeHeight = (HeightChance < 1.4) ? 7 : 8;
- var Type = (HeightChance < 1.4 && HeightChance > 0.9) ? 2 : 1;
-
- int SeperatorRadius = 1;
- int Radius = 2;
- int Offset = (HeightChance > 0.4 && HeightChance < 0.6) ? 1 : 0;
- for (int Y = Base.Y; Y < Base.Y + TreeHeight + 4; Y++)
- {
- if (Y - Base.Y <= TreeHeight)
- {
- chunk.SetBlockID(new Coordinates3D(Base.X, Y, Base.Z), WoodBlock.BlockID);
- chunk.SetMetadata(new Coordinates3D(Base.X, Y, Base.Z), Logs);
- }
- if (Y - Base.Y >= TreeHeight - 5)
- {
- int CurrentRadius = ((Offset % 2).Equals(0)) ? Radius : SeperatorRadius;
- if (Offset.Equals(0) && Type.Equals(2))
- CurrentRadius = 3;
- if (Y.Equals(Base.Y + TreeHeight + 1) || Y.Equals(Base.Y + TreeHeight + 3))
- CurrentRadius = SeperatorRadius;
- if (Y.Equals(Base.Y + TreeHeight + 2))
- {
- Coordinates3D Block = new Coordinates3D(Base.X, Y, Base.Z);
- chunk.SetBlockID(Block, LeavesBlock.BlockID);
- chunk.SetMetadata(Block, Leaves);
- continue;
- }
- GenerateCircleLeaves(chunk, new Coordinates3D(Base.X, Y, Base.Z), CurrentRadius, Leaves);
- Offset++;
- }
- }
- }
-
- private void GenerateCircleLeaves(IChunk chunk, Coordinates3D MiddleBlock, int Radius, byte Leaves, double CornerChance = 0)
- {
- for (int I = -Radius; I <= Radius; I = (I + 1))
- {
- for (int J = -Radius; J <= Radius; J = (J + 1))
- {
- int Max = (int)Math.Sqrt((I * I) + (J * J));
- if (Max <= Radius)
- {
- if (I.Equals(-Radius) && J.Equals(-Radius) || I.Equals(-Radius) && J.Equals(Radius) || I.Equals(Radius) && J.Equals(-Radius) || I.Equals(Radius) && J.Equals(Radius))
- {
- if (CornerChance + Radius * 0.2 < 0.4 || CornerChance + Radius * 0.2 > 0.7 || CornerChance.Equals(0))
- continue;
- }
- int X = MiddleBlock.X + I;
- int Z = MiddleBlock.Z + J;
- Coordinates3D CurrentBlock = new Coordinates3D(X, MiddleBlock.Y, Z);
- if (chunk.GetBlockID(CurrentBlock).Equals(0))
- {
- chunk.SetBlockID(CurrentBlock, LeavesBlock.BlockID);
- chunk.SetMetadata(CurrentBlock, Leaves);
- }
- }
- }
- }
- }
-
- private void GenerateSphereLeaves(IChunk chunk, Coordinates3D MiddleBlock, int Radius, byte Leaves)
- {
- for (int I = -Radius; I <= Radius; I = (I + 1))
- {
- for (int J = -Radius; J <= Radius; J = (J + 1))
- {
- for (int K = -Radius; K <= Radius; K = (K + 1))
- {
- int Max = (int)Math.Sqrt((I * I) + (J * J) + (K * K));
- if (Max <= Radius)
- {
- int X = MiddleBlock.X + I;
- int Y = MiddleBlock.Y + K;
- int Z = MiddleBlock.Z + J;
- Coordinates3D CurrentBlock = new Coordinates3D(X, Y, Z);
- if (chunk.GetBlockID(CurrentBlock).Equals(0))
- {
- chunk.SetBlockID(CurrentBlock, LeavesBlock.BlockID);
- chunk.SetMetadata(CurrentBlock, Leaves);
+ }
}
}
}
diff --git a/TrueCraft.Core/TerrainGen/NewGenerator.cs b/TrueCraft.Core/TerrainGen/NewGenerator.cs
index 124ec13..df3f7ea 100644
--- a/TrueCraft.Core/TerrainGen/NewGenerator.cs
+++ b/TrueCraft.Core/TerrainGen/NewGenerator.cs
@@ -9,6 +9,7 @@ using TrueCraft.Core.Logic.Blocks;
using TrueCraft.Core.TerrainGen.Noise;
using TrueCraft.Core.TerrainGen.Biomes;
using TrueCraft.Core.TerrainGen.Decorators;
+using TrueCraft.Core.TerrainGen.Decorations;
namespace TrueCraft.Core.TerrainGen
{
diff --git a/TrueCraft.Core/TrueCraft.Core.csproj b/TrueCraft.Core/TrueCraft.Core.csproj
index 7d5125c..e602728 100644
--- a/TrueCraft.Core/TrueCraft.Core.csproj
+++ b/TrueCraft.Core/TrueCraft.Core.csproj
@@ -182,6 +182,13 @@
+
+
+
+
+
+
+
diff --git a/TrueCraft.Core/World/Chunk.cs b/TrueCraft.Core/World/Chunk.cs
index 0699678..92b60f6 100644
--- a/TrueCraft.Core/World/Chunk.cs
+++ b/TrueCraft.Core/World/Chunk.cs
@@ -7,6 +7,7 @@ using fNbt;
using fNbt.Serialization;
using TrueCraft.API.World;
using TrueCraft.API;
+using TrueCraft.Core.Logic.Blocks;
namespace TrueCraft.Core.World
{
@@ -114,8 +115,10 @@ namespace TrueCraft.Core.World
IsModified = true;
int index = coordinates.Y + (coordinates.Z * Height) + (coordinates.X * Height * Width);
Blocks[index] = value;
+ if (value == AirBlock.BlockID)
+ Metadata[index] = 0x0;
var oldHeight = GetHeight((byte)coordinates.X, (byte)coordinates.Z);
- if (value == 0) // Air
+ if (value == AirBlock.BlockID)
{
if (oldHeight <= coordinates.Y)
{