using System; using System.Collections.Generic; using System.Linq; using System.Text; using MinecraftClient.Mapping.BlockPalettes; namespace MinecraftClient.Mapping { /// /// Represents a Minecraft Block /// public struct Block { /// /// Get or set global block ID to Material mapping /// The global Palette is a concept introduced with Minecraft 1.13 /// public static BlockPaletteMapping Palette { get; set; } /// /// Storage for block ID and metadata, as ushort for compatibility, performance and lower memory footprint /// For Minecraft 1.12 and lower, first 12 bits contain block ID (0-4095), last 4 bits contain metadata (0-15) /// For Minecraft 1.13 and greater, all 16 bits are used to store block state ID (0-65535) /// private ushort blockIdAndMeta; /// /// Id of the block /// public int BlockId { get { if (Palette.IdHasMetadata) { return blockIdAndMeta >> 4; } return blockIdAndMeta; } set { if (Palette.IdHasMetadata) { if (value > (ushort.MaxValue >> 4) || value < 0) throw new ArgumentOutOfRangeException("value", "Invalid block ID. Accepted range: 0-4095"); blockIdAndMeta = (ushort)(value << 4 | BlockMeta); } else { if (value > ushort.MaxValue || value < 0) throw new ArgumentOutOfRangeException("value", "Invalid block ID. Accepted range: 0-65535"); blockIdAndMeta = (ushort)value; } } } /// /// Metadata of the block. /// This field has no effect starting with Minecraft 1.13. /// public byte BlockMeta { get { if (Palette.IdHasMetadata) { return (byte)(blockIdAndMeta & 0x0F); } return 0; } set { if (Palette.IdHasMetadata) { blockIdAndMeta = (ushort)((blockIdAndMeta & ~0x0F) | (value & 0x0F)); } } } /// /// Material of the block /// public Material Type { get { return Palette.FromId(BlockId); } } /// /// Get a block of the specified type and metadata /// /// Block type /// Block metadata public Block(short type, byte metadata) { if (!Palette.IdHasMetadata) throw new InvalidOperationException("Current global Palette does not support block Metadata"); this.blockIdAndMeta = 0; this.BlockId = type; this.BlockMeta = metadata; } /// /// Get a block of the specified type and metadata OR block state /// /// Type and metadata packed in the same value OR block state public Block(ushort typeAndMeta) { this.blockIdAndMeta = typeAndMeta; } /// /// String representation of the block /// public override string ToString() { return BlockId.ToString() + (BlockMeta != 0 ? ":" + BlockMeta.ToString() : ""); } } }