diff --git a/TrueCraft.API/Logic/IItemRepository.cs b/TrueCraft.API/Logic/IItemRepository.cs new file mode 100644 index 0000000..5a8d2c0 --- /dev/null +++ b/TrueCraft.API/Logic/IItemRepository.cs @@ -0,0 +1,21 @@ +using System; + +namespace TrueCraft.API.Logic +{ + /// + /// Providers item providers for a server. + /// + public interface IItemRepository + { + /// + /// Gets this repository's item provider for the specified item ID. This may return null + /// if the item ID in question has no corresponding block provider. + /// + IItemProvider GetItemProvider(short id); + /// + /// Registers a new item provider. This overrides any existing item providers that use the + /// same item ID. + /// + void RegisterItemProvider(IItemProvider provider); + } +} \ No newline at end of file diff --git a/TrueCraft.API/Server/IMultiplayerServer.cs b/TrueCraft.API/Server/IMultiplayerServer.cs index 655c29e..cbd3a99 100644 --- a/TrueCraft.API/Server/IMultiplayerServer.cs +++ b/TrueCraft.API/Server/IMultiplayerServer.cs @@ -24,6 +24,7 @@ namespace TrueCraft.API.Server IList Worlds { get; } IEventScheduler Scheduler { get; } IBlockRepository BlockRepository { get; } + IItemRepository ItemRepository { get; } void Start(IPEndPoint endPoint); void RegisterPacketHandler(byte packetId, PacketHandler handler); diff --git a/TrueCraft.API/TrueCraft.API.csproj b/TrueCraft.API/TrueCraft.API.csproj index 5ed73b7..73a3a64 100644 --- a/TrueCraft.API/TrueCraft.API.csproj +++ b/TrueCraft.API/TrueCraft.API.csproj @@ -83,6 +83,7 @@ + diff --git a/TrueCraft.Core/Logic/Blocks/ClayBlock.cs b/TrueCraft.Core/Logic/Blocks/ClayBlock.cs index f0ebac7..95b9711 100644 --- a/TrueCraft.Core/Logic/Blocks/ClayBlock.cs +++ b/TrueCraft.Core/Logic/Blocks/ClayBlock.cs @@ -1,5 +1,8 @@ using System; using TrueCraft.API.Logic; +using TrueCraft.API; +using TrueCraft.API.World; +using TrueCraft.Core.Logic.Items; namespace TrueCraft.Core.Logic.Blocks { @@ -21,5 +24,10 @@ namespace TrueCraft.Core.Logic.Blocks { return new Tuple(8, 4); } + + protected override ItemStack[] GetDrop(BlockDescriptor descriptor) + { + return new[] { new ItemStack(ClayItem.ItemID, 4) }; + } } } \ No newline at end of file diff --git a/TrueCraft.Core/Logic/Blocks/LeavesBlock.cs b/TrueCraft.Core/Logic/Blocks/LeavesBlock.cs index fc1931b..58b8014 100644 --- a/TrueCraft.Core/Logic/Blocks/LeavesBlock.cs +++ b/TrueCraft.Core/Logic/Blocks/LeavesBlock.cs @@ -1,5 +1,7 @@ using System; using TrueCraft.API.Logic; +using TrueCraft.API; +using TrueCraft.API.World; namespace TrueCraft.Core.Logic.Blocks { @@ -25,5 +27,13 @@ namespace TrueCraft.Core.Logic.Blocks { return new Tuple(4, 3); } + + protected override ItemStack[] GetDrop(BlockDescriptor descriptor) + { + if (MathHelper.Random.Next(20) == 0) // 5% chance + return new[] { new ItemStack(SaplingBlock.BlockID, 1, descriptor.Metadata) }; + else + return new ItemStack[0]; + } } } \ No newline at end of file diff --git a/TrueCraft/Handlers/InteractionHandlers.cs b/TrueCraft/Handlers/InteractionHandlers.cs index 6b10319..f2a3ee7 100644 --- a/TrueCraft/Handlers/InteractionHandlers.cs +++ b/TrueCraft/Handlers/InteractionHandlers.cs @@ -18,6 +18,7 @@ namespace TrueCraft.Handlers var world = _client.World; var position = new Coordinates3D(packet.X, packet.Y, packet.Z); var descriptor = world.GetBlockData(position); + var provider = server.BlockRepository.GetBlockProvider(descriptor.ID); switch (packet.PlayerAction) { case PlayerDiggingPacket.Action.DropItem: @@ -30,6 +31,8 @@ namespace TrueCraft.Handlers if (c.KnownEntities.Contains(client.Entity)) c.QueuePacket(new AnimationPacket(client.Entity.EntityID, AnimationPacket.PlayerAnimation.SwingArm)); } + if (provider.Hardness == 0) + provider.BlockMined(descriptor, packet.Face, world, client); break; case PlayerDiggingPacket.Action.StopDigging: foreach (var nearbyClient in server.Clients) @@ -38,7 +41,6 @@ namespace TrueCraft.Handlers if (c.KnownEntities.Contains(client.Entity)) c.QueuePacket(new AnimationPacket(client.Entity.EntityID, AnimationPacket.PlayerAnimation.None)); } - var provider = server.BlockRepository.GetBlockProvider(descriptor.ID); provider.BlockMined(descriptor, packet.Face, world, client); break; } diff --git a/TrueCraft/ItemRepository.cs b/TrueCraft/ItemRepository.cs new file mode 100644 index 0000000..cea01e6 --- /dev/null +++ b/TrueCraft/ItemRepository.cs @@ -0,0 +1,71 @@ +using System; +using TrueCraft.API.Logic; +using System.Collections.Generic; +using System.Linq; +using TrueCraft.API.Entities; +using TrueCraft.API; +using TrueCraft.API.World; + +namespace TrueCraft +{ + public class ItemRepository : IItemRepository + { + public ItemRepository() + { + ItemProviders = new List(); + } + + private readonly List ItemProviders = new List(); + + public IItemProvider GetItemProvider(short id) + { + int max = ItemProviders.Count - 1, min = 0; + while (max >= min) + { + int mid = (max - min / 2) + min; + if (ItemProviders[mid].ID == id) + return ItemProviders[mid]; + else if(ItemProviders[mid].ID < id) + min = mid + 1; + else + max = min - 1; + } + return null; + } + + public void RegisterItemProvider(IItemProvider provider) + { + int i; + for (i = ItemProviders.Count - 1; i >= 0; i--) + { + if (provider.ID == ItemProviders[i].ID) + { + ItemProviders[i] = provider; // Override + return; + } + if (ItemProviders[i].ID < provider.ID) + break; + } + ItemProviders.Insert(i + 1, provider); + } + + internal void DiscoverItemProviders() + { + var providerTypes = new List(); + foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) + { + foreach (var type in assembly.GetTypes().Where(t => + typeof(IItemProvider).IsAssignableFrom(t) && !t.IsAbstract)) + { + providerTypes.Add(type); + } + } + + providerTypes.ForEach(t => + { + var instance = (IItemProvider)Activator.CreateInstance(t); + RegisterItemProvider(instance); + }); + } + } +} \ No newline at end of file diff --git a/TrueCraft/MultiplayerServer.cs b/TrueCraft/MultiplayerServer.cs index 2c6daf1..7009e2c 100644 --- a/TrueCraft/MultiplayerServer.cs +++ b/TrueCraft/MultiplayerServer.cs @@ -27,6 +27,7 @@ namespace TrueCraft public IList EntityManagers { get; private set; } public IEventScheduler Scheduler { get; private set; } public IBlockRepository BlockRepository { get; private set; } + public IItemRepository ItemRepository { get; private set; } private Timer EnvironmentWorker; private Thread NetworkWorker; @@ -49,6 +50,9 @@ namespace TrueCraft var blockRepository = new BlockRepository(); blockRepository.DiscoverBlockProviders(); BlockRepository = blockRepository; + var itemRepository = new ItemRepository(); + itemRepository.DiscoverItemProviders(); + ItemRepository = itemRepository; reader.RegisterCorePackets(); Handlers.PacketHandlers.RegisterHandlers(this); diff --git a/TrueCraft/TrueCraft.csproj b/TrueCraft/TrueCraft.csproj index 0f6d5d0..96097b3 100644 --- a/TrueCraft/TrueCraft.csproj +++ b/TrueCraft/TrueCraft.csproj @@ -54,6 +54,7 @@ +