This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
Drew DeVault a361703746 Implement walking sounds
These sounds change depending on what kind of block you're walking in.

Still to come: sound effects for mining and placing blocks
2015-10-05 22:06:59 -04:00

236 lines
8.8 KiB
C#

using System;
using TrueCraft.API;
using TrueCraft.Core.Logic.Items;
using TrueCraft.API.Logic;
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
{
public class ChestBlock : BlockProvider, ICraftingRecipe
{
public static readonly byte BlockID = 0x36;
public override byte ID { get { return 0x36; } }
public override double BlastResistance { get { return 12.5; } }
public override double Hardness { get { return 2.5; } }
public override byte Luminance { get { return 0; } }
public override bool Opaque { get { return false; } }
public override string DisplayName { get { return "Chest"; } }
public override SoundEffectClass SoundEffect
{
get
{
return SoundEffectClass.Wood;
}
}
public override Tuple<int, int> GetTextureMap(byte metadata)
{
return new Tuple<int, int>(10, 1);
}
public ItemStack[,] Pattern
{
get
{
return new[,]
{
{
new ItemStack(WoodenPlanksBlock.BlockID),
new ItemStack(WoodenPlanksBlock.BlockID),
new ItemStack(WoodenPlanksBlock.BlockID)
},
{
new ItemStack(WoodenPlanksBlock.BlockID),
ItemStack.EmptyStack,
new ItemStack(WoodenPlanksBlock.BlockID)
},
{
new ItemStack(WoodenPlanksBlock.BlockID),
new ItemStack(WoodenPlanksBlock.BlockID),
new ItemStack(WoodenPlanksBlock.BlockID)
}
};
}
}
public ItemStack Output
{
get { return new ItemStack(BlockID); }
}
public bool SignificantMetadata
{
get { return false; }
}
private static readonly Coordinates3D[] AdjacentBlocks =
{
Coordinates3D.North,
Coordinates3D.South,
Coordinates3D.West,
Coordinates3D.East
};
public override void ItemUsedOnBlock(Coordinates3D coordinates, ItemStack item, BlockFace face, IWorld world, IRemoteClient user)
{
int adjacent = 0;
var coords = coordinates + MathHelper.BlockFaceToCoordinates(face);
Coordinates3D _ = Coordinates3D.Down;
// Check for adjacent chests. We can only allow one adjacent check block.
for (int i = 0; i < AdjacentBlocks.Length; i++)
{
if (world.GetBlockID(coords + AdjacentBlocks[i]) == ChestBlock.BlockID)
{
_ = coords + AdjacentBlocks[i];
adjacent++;
}
}
if (adjacent <= 1)
{
if (_ != Coordinates3D.Down)
{
// Confirm that adjacent chest is not a double chest
for (int i = 0; i < AdjacentBlocks.Length; i++)
{
if (world.GetBlockID(_ + AdjacentBlocks[i]) == ChestBlock.BlockID)
adjacent++;
}
}
if (adjacent <= 1)
base.ItemUsedOnBlock(coordinates, item, face, world, user);
}
}
public override void BlockPlaced(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user)
{
world.SetMetadata(descriptor.Coordinates, (byte)MathHelper.DirectionByRotationFlat(user.Entity.Yaw, true));
}
public override bool BlockRightClicked(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user)
{
var adjacent = -Coordinates3D.One; // -1, no adjacent chest
var self = descriptor.Coordinates;
for (int i = 0; i < AdjacentBlocks.Length; i++)
{
var test = self + AdjacentBlocks[i];
if (world.GetBlockID(test) == ChestBlock.BlockID)
{
adjacent = test;
var up = world.BlockRepository.GetBlockProvider(world.GetBlockID(test + Coordinates3D.Up));
if (up.Opaque && !(up is WallSignBlock)) // Wall sign blocks are an exception
return false; // Obstructed
break;
}
}
var upSelf = world.BlockRepository.GetBlockProvider(world.GetBlockID(self + Coordinates3D.Up));
if (upSelf.Opaque && !(upSelf is WallSignBlock))
return false; // Obstructed
if (adjacent != -Coordinates3D.One)
{
// 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)
{
foreach (var item in (NbtList)entity["Items"])
{
var slot = ItemStack.FromNbt((NbtCompound)item);
window.ChestInventory[slot.Index] = slot;
}
}
// Add adjacent items
if (adjacent != -Coordinates3D.One)
{
entity = world.GetTileEntity(adjacent);
if (entity != null)
{
foreach (var item in (NbtList)entity["Items"])
{
var slot = ItemStack.FromNbt((NbtCompound)item);
window.ChestInventory[slot.Index + ChestWindow.DoubleChestSecondaryIndex] = slot;
}
}
}
window.WindowChange += (sender, e) =>
{
var entitySelf = new NbtList("Items", NbtTagType.Compound);
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);
}
};
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);
}
}
}