Refactor chest code, implement storage persistence

This commit is contained in:
Drew DeVault 2015-06-21 21:55:41 -04:00
parent a2f9003dad
commit 81acdf103a
3 changed files with 75 additions and 29 deletions

View File

@ -110,51 +110,98 @@ namespace TrueCraft.Core.Logic.Blocks
public override bool BlockRightClicked(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user) public override bool BlockRightClicked(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user)
{ {
bool unobstructed = true, isDouble = false; var adjacent = -Coordinates3D.One; // -1, no adjacent chest
Coordinates3D other = Coordinates3D.Down; var self = descriptor.Coordinates;
for (int i = 0; i < AdjacentBlocks.Length; i++) for (int i = 0; i < AdjacentBlocks.Length; i++)
{ {
if (world.GetBlockID(descriptor.Coordinates + AdjacentBlocks[i]) == ChestBlock.BlockID) var test = self + AdjacentBlocks[i];
if (world.GetBlockID(test) == ChestBlock.BlockID)
{ {
isDouble = true; adjacent = test;
other = descriptor.Coordinates + AdjacentBlocks[i]; var up = world.BlockRepository.GetBlockProvider(world.GetBlockID(test + Coordinates3D.Up));
var _ = world.BlockRepository.GetBlockProvider(world.GetBlockID( if (up.Opaque)
descriptor.Coordinates + AdjacentBlocks[i] + Coordinates3D.Up)); return false; // Obstructed
if (_.Opaque) break;
unobstructed = false;
} }
} }
if (world.BlockRepository.GetBlockProvider(world.GetBlockID(descriptor.Coordinates + Coordinates3D.Up)).Opaque) var upSelf = world.BlockRepository.GetBlockProvider(world.GetBlockID(self + Coordinates3D.Up));
unobstructed = false; if (upSelf.Opaque)
if (!unobstructed) return false; // Obstructed
return false;
var entity = world.GetTileEntity(descriptor.Coordinates); if (adjacent != -Coordinates3D.One)
var window = new ChestWindow((InventoryWindow)user.Inventory, isDouble); {
// Ensure that chests are always opened in the same arrangement
if (adjacent.X < self.X ||
adjacent.Z < self.Z)
{
var _ = adjacent;
adjacent = self;
self = _; // Swap
}
}
var window = new ChestWindow((InventoryWindow)user.Inventory, adjacent != -Coordinates3D.One);
// Add items
var entity = world.GetTileEntity(self);
if (entity != null) if (entity != null)
{ {
foreach (NbtCompound item in (NbtList)entity["Items"]) foreach (var item in (NbtList)entity["Items"])
{ {
var stack = ItemStack.FromNbt(item); var slot = ItemStack.FromNbt((NbtCompound)item);
window.ChestInventory[stack.Index] = stack; window.ChestInventory[slot.Index] = slot;
} }
} }
if (isDouble) // Add adjacent items
if (adjacent != -Coordinates3D.One)
{ {
entity = world.GetTileEntity(other); entity = world.GetTileEntity(adjacent);
if (entity != null) if (entity != null)
{ {
foreach (NbtCompound item in (NbtList)entity["Items"]) foreach (var item in (NbtList)entity["Items"])
{ {
var stack = ItemStack.FromNbt(item); var slot = ItemStack.FromNbt((NbtCompound)item);
window.ChestInventory[stack.Index] = stack; window.ChestInventory[slot.Index + ChestWindow.DoubleChestSecondaryIndex] = slot;
} }
} }
} }
user.OpenWindow(window);
window.WindowChange += (sender, e) => window.WindowChange += (sender, e) =>
{ {
// TODO: Update tile entity var entitySelf = new NbtList("Items", NbtTagType.Compound);
}; // TODO: Memory leak here var entityAdjacent = new NbtList("Items", NbtTagType.Compound);
for (int i = 0; i < window.ChestInventory.Items.Length; i++)
{
var item = window.ChestInventory.Items[i];
if (!item.Empty)
{
if (i < ChestWindow.DoubleChestSecondaryIndex)
{
item.Index = i;
entitySelf.Add(item.ToNbt());
}
else
{
item.Index = i - ChestWindow.DoubleChestSecondaryIndex;
entityAdjacent.Add(item.ToNbt());
}
}
}
var newEntity = world.GetTileEntity(self);
if (newEntity == null)
newEntity = new NbtCompound(new[] { entitySelf });
else
newEntity["Items"] = entitySelf;
world.SetTileEntity(self, newEntity);
if (adjacent != -Coordinates3D.One)
{
newEntity = world.GetTileEntity(adjacent);
if (newEntity == null)
newEntity = new NbtCompound(new[] { entityAdjacent });
else
newEntity["Items"] = entityAdjacent;
world.SetTileEntity(adjacent, newEntity);
}
}; // TODO: Memory leak here, make windows implement IDisposable
user.OpenWindow(window);
return false; return false;
} }
} }

View File

@ -47,6 +47,7 @@ namespace TrueCraft.Core.Windows
} }
public const int ChestIndex = 0; public const int ChestIndex = 0;
public const int DoubleChestSecondaryIndex = 27;
public const int MainIndex = 27; public const int MainIndex = 27;
public const int HotbarIndex = 54; public const int HotbarIndex = 54;
public const int DoubleMainIndex = 54; public const int DoubleMainIndex = 54;

View File

@ -12,8 +12,6 @@ namespace TrueCraft.Core.World
{ {
public const int Width = 16, Height = 128, Depth = 16; public const int Width = 16, Height = 128, Depth = 16;
private static readonly NbtSerializer Serializer = new NbtSerializer(typeof(Chunk));
[NbtIgnore] [NbtIgnore]
public DateTime LastAccessed { get; set; } public DateTime LastAccessed { get; set; }
[NbtIgnore] [NbtIgnore]