diff --git a/TrueCraft.Core.Test/Lighting/WorldLighterTest.cs b/TrueCraft.Core.Test/Lighting/WorldLighterTest.cs index 9787c09..057827c 100644 --- a/TrueCraft.Core.Test/Lighting/WorldLighterTest.cs +++ b/TrueCraft.Core.Test/Lighting/WorldLighterTest.cs @@ -232,6 +232,94 @@ namespace TrueCraft.Core.Test.Lighting expected--; } } + + [Test] + public void TestLeavesAndEtc() + { + var repository = new BlockRepository(); + repository.RegisterBlockProvider(new GrassBlock()); + repository.RegisterBlockProvider(new DirtBlock()); + repository.RegisterBlockProvider(new AirBlock()); + repository.RegisterBlockProvider(new BedrockBlock()); + repository.RegisterBlockProvider(new LeavesBlock()); + var world = new TrueCraft.Core.World.World("TEST", new FlatlandGenerator()); + world.BlockRepository = repository; + var lighter = new WorldLighter(world, repository); + world.GetBlockID(Coordinates3D.Zero); // Generate a chunk + + for (int y = 1; y <= 16; y++) + { + var coords = new Coordinates3D(5, y, 5); + world.SetBlockID(coords, 0); + world.SetBlockID(coords + Coordinates3D.East, DirtBlock.BlockID); + world.SetBlockID(coords + Coordinates3D.West, DirtBlock.BlockID); + world.SetBlockID(coords + Coordinates3D.North, DirtBlock.BlockID); + world.SetBlockID(coords + Coordinates3D.South, DirtBlock.BlockID); + } + world.GetChunk(Coordinates2D.Zero).UpdateHeightMap(); + + lighter.EnqueueOperation(new BoundingBox( + new Vector3(0, 0, 0), + new Vector3(16, 128, 16)), true, true); + while (lighter.TryLightNext()) // Initial lighting + { + } + + // Test this layout: + // xox o == leaves + // x x + // xox + // x x + // xox ... + + for (int y = 1; y <= 16; y++) + { + if (y % 2 == 1) + world.SetBlockID(new Coordinates3D(5, y, 5), LeavesBlock.BlockID); + } + world.GetChunk(Coordinates2D.Zero).UpdateHeightMap(); + + lighter.EnqueueOperation(new BoundingBox(new Vector3(5, 0, 5), + new Vector3(6, 16, 6)), true); + + while (lighter.TryLightNext()) // Test lighting + { + } + + // Output lighting + for (int y = 16; y >= 0; y--) + { + Console.Write(world.GetBlockID(new Coordinates3D(5, y, 5)).ToString("D2")); + Console.Write(" " + world.GetSkyLight(new Coordinates3D(5, y, 5)).ToString("D2")); + Console.WriteLine(" Y={0}", y); + } + + var expected = new byte[] + { + 15, // air + 15, // leaves + 13, // air + 11, // leaves + 9, // air + 7, // leaves + 5, // air + 3, // leaves + 1, // air + 0, // leaves + 0, // air + 0, // leaves + }; + + for (int y = 16, i = 0; y >= 0; y--, i++) + { + byte ex; + if (i < expected.Length) + ex = expected[i]; + else + ex = 0; + Assert.AreEqual(ex, world.GetSkyLight(new Coordinates3D(5, y, 5))); + } + } } } diff --git a/TrueCraft.Core/Lighting/WorldLighter.cs b/TrueCraft.Core/Lighting/WorldLighter.cs index f0eeb18..62667ac 100644 --- a/TrueCraft.Core/Lighting/WorldLighter.cs +++ b/TrueCraft.Core/Lighting/WorldLighter.cs @@ -93,12 +93,14 @@ namespace TrueCraft.Core.Lighting byte current = op.SkyLight ? data.SkyLight : data.BlockLight; byte newLight = 0; byte opacity = Math.Max(provider.LightModifier, (byte)1); - byte emissiveness = Math.Max(provider.Luminance, op.SkyLight ? data.SkyLight : data.BlockLight); + byte emissiveness = provider.Luminance; if (op.SkyLight) { - if (chunk.GetHeight((byte)adjustedCoords.X, (byte)adjustedCoords.Z) <= y) + if (y >= chunk.GetHeight((byte)adjustedCoords.X, (byte)adjustedCoords.Z)) emissiveness = 15; } + else + emissiveness = provider.Luminance; if (opacity < 15 || emissiveness != 0) { byte max = 0; @@ -116,7 +118,7 @@ namespace TrueCraft.Core.Lighting else val = c.GetBlockLight(adjusted); var p = BlockRepository.GetBlockProvider(c.GetBlockID(adjusted)); - val -= p.LightModifier; + val -= Math.Max(0, p.LightModifier - 1); max = (byte)Math.Max(max, val); } } @@ -171,9 +173,9 @@ namespace TrueCraft.Core.Lighting if (op.Box.Min.DistanceTo(box.Min) <= 2 && op.Box.Max.DistanceTo(box.Max) <= 2 && op.Box.Volume - box.Volume <= 2) { - // Merge - op.Box = new BoundingBox(Vector3.Min(op.Box.Min, box.Min), Vector3.Max(op.Box.Max, box.Max)); - return; + // TODO: Merge + //op.Box = new BoundingBox(Vector3.Min(op.Box.Min, box.Min), Vector3.Max(op.Box.Max, box.Max)); + //return; } } PendingOperations.Add(new LightingOperation { SkyLight = skyLight, Box = box, Initial = initial }); diff --git a/TrueCraft.Core/Logic/BlockProvider.cs b/TrueCraft.Core/Logic/BlockProvider.cs index 49e565c..49ea7bd 100644 --- a/TrueCraft.Core/Logic/BlockProvider.cs +++ b/TrueCraft.Core/Logic/BlockProvider.cs @@ -208,7 +208,16 @@ namespace TrueCraft.Core.Logic /// - This isn't needed for opaque blocks /// - This is needed since some "partial" transparent blocks remove more than 1 level from light passing through such as Ice. /// - public virtual byte LightModifier { get { return 255; } } + public virtual byte LightModifier + { + get + { + if (Opaque) + return 255; + else + return 0; + } + } public virtual bool DiffuseSkyLight { get { return false; } } diff --git a/TrueCraft.Core/Logic/Blocks/AirBlock.cs b/TrueCraft.Core/Logic/Blocks/AirBlock.cs index edfa5ed..73aee09 100644 --- a/TrueCraft.Core/Logic/Blocks/AirBlock.cs +++ b/TrueCraft.Core/Logic/Blocks/AirBlock.cs @@ -16,8 +16,6 @@ namespace TrueCraft.Core.Logic.Blocks public override bool Opaque { get { return false; } } - public override byte LightModifier { get { return 0; } } - public override byte Luminance { get { return 0; } } public override string DisplayName { get { return "Air"; } } diff --git a/TrueCraft.Core/Logic/Blocks/LeavesBlock.cs b/TrueCraft.Core/Logic/Blocks/LeavesBlock.cs index f7bedaf..50971c3 100644 --- a/TrueCraft.Core/Logic/Blocks/LeavesBlock.cs +++ b/TrueCraft.Core/Logic/Blocks/LeavesBlock.cs @@ -20,7 +20,9 @@ namespace TrueCraft.Core.Logic.Blocks public override bool Opaque { get { return false; } } - //TODO: Mark this as a block that diffuses sun light. + public override bool DiffuseSkyLight { get { return true; } } + + public override byte LightModifier { get { return 2; } } public override string DisplayName { get { return "Leaves"; } } @@ -43,4 +45,4 @@ namespace TrueCraft.Core.Logic.Blocks } } } -} \ No newline at end of file +} diff --git a/TrueCraft/Program.cs b/TrueCraft/Program.cs index 6772979..08d3f58 100644 --- a/TrueCraft/Program.cs +++ b/TrueCraft/Program.cs @@ -89,6 +89,7 @@ namespace TrueCraft Server.Log(LogCategory.Notice, "{0}% complete", progress + 10); } } + world.Save(); CommandManager = new CommandManager(); Server.ChatMessageReceived += HandleChatMessageReceived; Server.Start(new IPEndPoint(IPAddress.Parse(ServerConfiguration.ServerAddress), ServerConfiguration.ServerPort));