Make chests drop inventory when mined

This also fixes a bug where a chest, when removed and replaced, would
have the same inventory. Also adds validation on update sign packets to
make sure it is indeed a sign they are updating.
This commit is contained in:
Drew DeVault 2015-06-22 10:38:12 -04:00
parent 81acdf103a
commit 20e0aee572
5 changed files with 60 additions and 19 deletions

View File

@ -6,6 +6,8 @@ using TrueCraft.API.World;
using TrueCraft.API.Networking;
using fNbt;
using TrueCraft.Core.Windows;
using System.Collections.Generic;
using TrueCraft.Core.Entities;
namespace TrueCraft.Core.Logic.Blocks
{
@ -204,5 +206,22 @@ namespace TrueCraft.Core.Logic.Blocks
user.OpenWindow(window);
return false;
}
public override void BlockMined(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user)
{
var self = descriptor.Coordinates;
var entity = world.GetTileEntity(self);
var manager = user.Server.GetEntityManagerForWorld(world);
if (entity != null)
{
foreach (var item in (NbtList)entity["Items"])
{
var slot = ItemStack.FromNbt((NbtCompound)item);
manager.SpawnEntity(new ItemEntity(descriptor.Coordinates + new Vector3(0.5), slot));
}
}
world.SetTileEntity(self, null);
base.BlockMined(descriptor, face, world, user);
}
}
}

View File

@ -44,6 +44,12 @@ namespace TrueCraft.Core.Logic.Blocks
return new[] { new ItemStack(SignItem.ItemID) };
}
public override void BlockMined(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user)
{
world.SetTileEntity(descriptor.Coordinates, null);
base.BlockMined(descriptor, face, world, user);
}
public override void TileEntityLoadedForClient(BlockDescriptor descriptor, IWorld world, NbtCompound entity, IRemoteClient client)
{
client.QueuePacket(new UpdateSignPacket

View File

@ -40,21 +40,27 @@ namespace TrueCraft.Core.Logic.Blocks
return new[] { new ItemStack(SignItem.ItemID) };
}
public override void BlockMined(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user)
{
world.SetTileEntity(descriptor.Coordinates, null);
base.BlockMined(descriptor, face, world, user);
}
public override void TileEntityLoadedForClient(BlockDescriptor descriptor, IWorld world, NbtCompound entity, IRemoteClient client)
{
client.QueuePacket(new UpdateSignPacket
{
X = descriptor.Coordinates.X,
Y = (short)descriptor.Coordinates.Y,
Z = descriptor.Coordinates.Z,
Text = new[]
{
X = descriptor.Coordinates.X,
Y = (short)descriptor.Coordinates.Y,
Z = descriptor.Coordinates.Z,
Text = new[]
{
entity["Text1"].StringValue,
entity["Text2"].StringValue,
entity["Text3"].StringValue,
entity["Text4"].StringValue
}
});
entity["Text1"].StringValue,
entity["Text2"].StringValue,
entity["Text3"].StringValue,
entity["Text4"].StringValue
}
});
}
}
}

View File

@ -177,7 +177,10 @@ namespace TrueCraft.Core.World
/// </summary>
public void SetTileEntity(Coordinates3D coordinates, NbtCompound value)
{
TileEntities[coordinates] = value;
if (value == null && TileEntities.ContainsKey(coordinates))
TileEntities.Remove(coordinates);
else
TileEntities[coordinates] = value;
IsModified = true;
}

View File

@ -9,6 +9,8 @@ using TrueCraft.Core.Windows;
using TrueCraft.API.Logic;
using TrueCraft.Core.Entities;
using fNbt;
using TrueCraft.Core.Logic.Blocks;
using System.Linq;
namespace TrueCraft.Handlers
{
@ -286,14 +288,19 @@ namespace TrueCraft.Handlers
var coords = new Coordinates3D(packet.X, packet.Y, packet.Z);
if (client.Entity.Position.DistanceTo(coords) < 10) // TODO: Reach
{
client.World.SetTileEntity(coords, new NbtCompound(new[]
var block = client.World.GetBlockID(coords);
if (block == UprightSignBlock.BlockID || block == WallSignBlock.BlockID)
{
new NbtString("Text1", packet.Text[0]),
new NbtString("Text2", packet.Text[1]),
new NbtString("Text3", packet.Text[2]),
new NbtString("Text4", packet.Text[3]),
}));
client.QueuePacket(packet);
client.World.SetTileEntity(coords, new NbtCompound(new[]
{
new NbtString("Text1", packet.Text[0]),
new NbtString("Text2", packet.Text[1]),
new NbtString("Text3", packet.Text[2]),
new NbtString("Text4", packet.Text[3]),
}));
// TODO: Some utility methods for things like "clients with given chunk loaded"
server.Clients.Where(c => ((RemoteClient)c).LoggedIn && c.World == _client.World).ToList().ForEach(c => c.QueuePacket(packet));
}
}
}
}