diff --git a/TrueCraft.API/World/IWorld.cs b/TrueCraft.API/World/IWorld.cs index fd024c1..b9baeb1 100644 --- a/TrueCraft.API/World/IWorld.cs +++ b/TrueCraft.API/World/IWorld.cs @@ -10,6 +10,7 @@ namespace TrueCraft.API.World public interface IWorld { string Name { get; set; } + IBlockRepository BlockRepository { get; set; } IChunkProvider ChunkProvider { get; set; } long Time { get; set; } diff --git a/TrueCraft.Core/Logic/BlockProvider.cs b/TrueCraft.Core/Logic/BlockProvider.cs index d060ac5..1442ecd 100644 --- a/TrueCraft.Core/Logic/BlockProvider.cs +++ b/TrueCraft.Core/Logic/BlockProvider.cs @@ -36,6 +36,7 @@ namespace TrueCraft.Core.Logic var items = GetDrop(descriptor); foreach (var item in items) { + if (item.Empty) continue; var entity = new ItemEntity(new Vector3(descriptor.Coordinates) + new Vector3(0.5), item); entityManager.SpawnEntity(entity); } diff --git a/TrueCraft.Core/Logic/Blocks/CropsBlock.cs b/TrueCraft.Core/Logic/Blocks/CropsBlock.cs index 687ccc9..6c35681 100644 --- a/TrueCraft.Core/Logic/Blocks/CropsBlock.cs +++ b/TrueCraft.Core/Logic/Blocks/CropsBlock.cs @@ -1,5 +1,10 @@ using System; using TrueCraft.API.Logic; +using TrueCraft.API; +using TrueCraft.Core.Logic.Items; +using TrueCraft.API.Networking; +using TrueCraft.API.World; +using TrueCraft.API.Server; namespace TrueCraft.Core.Logic.Blocks { @@ -23,5 +28,42 @@ namespace TrueCraft.Core.Logic.Blocks { return new Tuple(8, 5); } + + protected override ItemStack[] GetDrop(BlockDescriptor descriptor) + { + if (descriptor.Metadata >= 7) + return new[] { new ItemStack(WheatItem.ItemID), new ItemStack(SeedsItem.ItemID, (sbyte)MathHelper.Random.Next(3)) }; + else + return new[] { new ItemStack(SeedsItem.ItemID) }; + } + + private void GrowBlock(IMultiplayerServer server, IWorld world, Coordinates3D coords) + { + if (world.GetBlockID(coords) != BlockID) + return; + var meta = world.GetMetadata(coords); + meta++; + world.SetMetadata(coords, meta); + if (meta < 7) + { + server.Scheduler.ScheduleEvent(DateTime.Now.AddSeconds(MathHelper.Random.Next(30, 60)), + (_server) => GrowBlock(_server, world, coords)); + } + } + + public override void BlockUpdate(BlockDescriptor descriptor, IMultiplayerServer server, IWorld world) + { + if (world.GetBlockID(descriptor.Coordinates + Coordinates3D.Down) != FarmlandBlock.BlockID) + { + GenerateDropEntity(descriptor, world, server); + world.SetBlockID(descriptor.Coordinates, 0); + } + } + + public override void BlockPlaced(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user) + { + user.Server.Scheduler.ScheduleEvent(DateTime.Now.AddSeconds(MathHelper.Random.Next(30, 60)), + (server) => GrowBlock(server, world, descriptor.Coordinates + MathHelper.BlockFaceToCoordinates(face))); + } } } \ No newline at end of file diff --git a/TrueCraft.Core/Logic/Blocks/FarmlandBlock.cs b/TrueCraft.Core/Logic/Blocks/FarmlandBlock.cs index de8c435..f4ec7c1 100644 --- a/TrueCraft.Core/Logic/Blocks/FarmlandBlock.cs +++ b/TrueCraft.Core/Logic/Blocks/FarmlandBlock.cs @@ -1,5 +1,9 @@ using System; using TrueCraft.API.Logic; +using TrueCraft.API.Networking; +using TrueCraft.API.World; +using TrueCraft.API; +using TrueCraft.API.Server; namespace TrueCraft.Core.Logic.Blocks { @@ -25,5 +29,51 @@ namespace TrueCraft.Core.Logic.Blocks { return new Tuple(7, 5); } + + public bool IsHydrated(Coordinates3D coordinates, IWorld world) + { + var min = new Coordinates3D(-6 + coordinates.X, coordinates.Y, -6 + coordinates.Z); + var max = new Coordinates3D(6 + coordinates.X, coordinates.Y + 1, 6 + coordinates.Z); + for (int x = min.X; x < max.X; x++) + { + for (int y = min.Y; y < max.Y; y++) // TODO: This does not check one above the farmland block for some reason + { + for (int z = min.Z; z < max.Z; z++) + { + var id = world.GetBlockID(new Coordinates3D(x, y, z)); + if (id == WaterBlock.BlockID || id == StationaryWaterBlock.BlockID) + return true; + } + } + } + return false; + } + + void HydrationCheckEvent(IMultiplayerServer server, Coordinates3D coords, IWorld world) + { + if (world.GetBlockID(coords) != BlockID) + return; + if (MathHelper.Random.Next(3) == 0) + { + if (IsHydrated(coords, world)) + { + world.SetMetadata(coords, 15); + } + else + { + world.SetBlockID(coords, DirtBlock.BlockID); + } + } + server.Scheduler.ScheduleEvent(DateTime.Now.AddSeconds(30), (_server) => HydrationCheckEvent(_server, coords, world)); + } + + public override void BlockPlaced(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user) + { + if (IsHydrated(descriptor.Coordinates, world)) + { + world.SetMetadata(descriptor.Coordinates, 15); + } + user.Server.Scheduler.ScheduleEvent(DateTime.Now.AddSeconds(30), (server) => HydrationCheckEvent(server, descriptor.Coordinates, world)); + } } } \ No newline at end of file diff --git a/TrueCraft.Core/Logic/Items/HoeItem.cs b/TrueCraft.Core/Logic/Items/HoeItem.cs index 6414eb1..ce53840 100644 --- a/TrueCraft.Core/Logic/Items/HoeItem.cs +++ b/TrueCraft.Core/Logic/Items/HoeItem.cs @@ -67,6 +67,8 @@ namespace TrueCraft.Core.Logic.Items if (id == DirtBlock.BlockID || id == GrassBlock.BlockID) { world.SetBlockID(coordinates, FarmlandBlock.BlockID); + user.Server.BlockRepository.GetBlockProvider(FarmlandBlock.BlockID).BlockPlaced( + new BlockDescriptor { Coordinates = coordinates }, face, world, user); } } } diff --git a/TrueCraft.Core/Logic/Items/SeedsItem.cs b/TrueCraft.Core/Logic/Items/SeedsItem.cs index 40216fc..0244369 100644 --- a/TrueCraft.Core/Logic/Items/SeedsItem.cs +++ b/TrueCraft.Core/Logic/Items/SeedsItem.cs @@ -1,5 +1,9 @@ using System; using TrueCraft.API.Logic; +using TrueCraft.API; +using TrueCraft.API.World; +using TrueCraft.API.Networking; +using TrueCraft.Core.Logic.Blocks; namespace TrueCraft.Core.Logic.Items { @@ -10,5 +14,15 @@ namespace TrueCraft.Core.Logic.Items public override short ID { get { return 0x127; } } public override string DisplayName { get { return "Seeds"; } } + + public override void ItemUsedOnBlock(Coordinates3D coordinates, ItemStack item, BlockFace face, IWorld world, IRemoteClient user) + { + if (world.GetBlockID(coordinates) == FarmlandBlock.BlockID) + { + world.SetBlockID(coordinates + MathHelper.BlockFaceToCoordinates(face), CropsBlock.BlockID); + world.BlockRepository.GetBlockProvider(CropsBlock.BlockID).BlockPlaced( + new BlockDescriptor { Coordinates = coordinates }, face, world, user); + } + } } } \ No newline at end of file diff --git a/TrueCraft.Core/World/World.cs b/TrueCraft.Core/World/World.cs index 3048061..cf9ee74 100644 --- a/TrueCraft.Core/World/World.cs +++ b/TrueCraft.Core/World/World.cs @@ -17,6 +17,7 @@ namespace TrueCraft.Core.World public string BaseDirectory { get; internal set; } public IDictionary Regions { get; set; } public IChunkProvider ChunkProvider { get; set; } + public IBlockRepository BlockRepository { get; set; } public DateTime BaseTime { get; set; } public long Time { diff --git a/TrueCraft/MultiplayerServer.cs b/TrueCraft/MultiplayerServer.cs index 0bfb860..f004c4d 100644 --- a/TrueCraft/MultiplayerServer.cs +++ b/TrueCraft/MultiplayerServer.cs @@ -107,6 +107,7 @@ namespace TrueCraft public void AddWorld(IWorld world) { Worlds.Add(world); + world.BlockRepository = BlockRepository; world.BlockChanged += HandleBlockChanged; var manager = new EntityManager(this, world); EntityManagers.Add(manager);