diff --git a/Minecraft.Server.FourKit/Material/Attachable.cs b/Minecraft.Server.FourKit/Material/Attachable.cs new file mode 100644 index 000000000..1ce852f4f --- /dev/null +++ b/Minecraft.Server.FourKit/Material/Attachable.cs @@ -0,0 +1,7 @@ +using Minecraft.Server.FourKit.Block; +namespace Minecraft.Server.FourKit.material; + +public interface Attachable : Directional +{ + public BlockFace getAttachedFace(); +} \ No newline at end of file diff --git a/Minecraft.Server.FourKit/Material/Directional.cs b/Minecraft.Server.FourKit/Material/Directional.cs new file mode 100644 index 000000000..b3ce21004 --- /dev/null +++ b/Minecraft.Server.FourKit/Material/Directional.cs @@ -0,0 +1,8 @@ +using Minecraft.Server.FourKit.Block; +namespace Minecraft.Server.FourKit.material; + +public interface Directional +{ + public void setFacingDirection(BlockFace face); + public BlockFace getFacing(); +} \ No newline at end of file diff --git a/Minecraft.Server.FourKit/Material/MaterialData.cs b/Minecraft.Server.FourKit/Material/MaterialData.cs new file mode 100644 index 000000000..54d701480 --- /dev/null +++ b/Minecraft.Server.FourKit/Material/MaterialData.cs @@ -0,0 +1,48 @@ +namespace Minecraft.Server.FourKit.material; + +public class MaterialData +{ + private readonly int _typeId; + private byte _data = 0; + + public MaterialData(int typeId) : this(typeId, (byte)0) { } + + public MaterialData(Material type) : this((int)type, (byte)0) { } + + public MaterialData(int typeId, byte data) + { + _typeId = typeId; + _data = data; + } + + public MaterialData(Material type, byte data) : this((int)type, data) { } + + /// + /// Gets the raw data in this material + /// + /// raw data + public byte getData() => _data; + + /// + /// Sets the raw data of this material + /// + /// New raw data + public void setData(byte data) { + _data = data; + } + + /// + /// Gets the Material that this MaterialData represents + /// + /// Material represented by this MaterialData + public Material getItemType() => (Material)_typeId; + + /// + /// Gets the Material Id that this MaterialData represents + /// + /// Material Id represented by this MaterialData + public int getItemTypeId() => _typeId; + + + public override string ToString() => $"{getItemType()}({getData()})"; +} \ No newline at end of file diff --git a/Minecraft.Server.FourKit/Material/Sign.cs b/Minecraft.Server.FourKit/Material/Sign.cs new file mode 100644 index 000000000..05cb0fcf5 --- /dev/null +++ b/Minecraft.Server.FourKit/Material/Sign.cs @@ -0,0 +1,123 @@ +using Minecraft.Server.FourKit.Block; + +namespace Minecraft.Server.FourKit.material; + +public class Sign : MaterialData, Attachable +{ + public Sign() : base((int)Material.SIGN_POST) { } + + public Sign(int typeId) : base(typeId) { } + + public Sign(Material type) : base(type) { } + + public Sign(int typeId, byte data) : base(typeId, data) { } + + public Sign(Material type, byte data) : base(type, data) { } + + /// + /// Check if this sign is attached to a wall + /// + /// true if this sign is attached to a wall, false if set on top of + /// a block + public bool isWallSign() + { + return getItemType() == Material.WALL_SIGN; + } + + /// + /// Gets the face that this block is attached on + /// + /// BlockFace attached to + public BlockFace getAttachedFace() + { + if (!isWallSign()) + { + return BlockFace.DOWN; + } + + return getData() switch{ + 0x2 => BlockFace.SOUTH, + 0x3 => BlockFace.NORTH, + 0x4 => BlockFace.EAST, + 0x5 => BlockFace.WEST, + _ => BlockFace.SELF + }; + } + + /// + /// Gets the direction that this sign is currently facing + /// + /// BlockFace indicating where this sign is facing + public BlockFace getFacing() + { + if (isWallSign()) + { + return getAttachedFace().getOppositeFace(); + } + + return getData() switch + { + 0x0 => BlockFace.SOUTH, + 0x1 => BlockFace.SOUTH_SOUTH_WEST, + 0x2 => BlockFace.SOUTH_WEST, + 0x3 => BlockFace.WEST_SOUTH_WEST, + 0x4 => BlockFace.WEST, + 0x5 => BlockFace.WEST_NORTH_WEST, + 0x6 => BlockFace.NORTH_WEST, + 0x7 => BlockFace.NORTH_NORTH_WEST, + 0x8 => BlockFace.NORTH, + 0x9 => BlockFace.NORTH_NORTH_EAST, + 0xA => BlockFace.NORTH_EAST, + 0xB => BlockFace.EAST_NORTH_EAST, + 0xC => BlockFace.EAST, + 0xD => BlockFace.EAST_SOUTH_EAST, + 0xE => BlockFace.SOUTH_EAST, + 0xF => BlockFace.SOUTH_SOUTH_EAST, + _ => BlockFace.SELF + }; + } + + /// + /// Sets the direction that this sign is currently facing + /// + /// BlockFace Direction to point + public void setFacingDirection(BlockFace face) + { + byte data = (byte)( + isWallSign() + ? face switch + { + BlockFace.NORTH => 0x2, + BlockFace.SOUTH => 0x3, + BlockFace.WEST => 0x4, + _ => 0x5 // EAST/default + } + : face switch + { + BlockFace.SOUTH => 0x0, + BlockFace.SOUTH_SOUTH_WEST => 0x1, + BlockFace.SOUTH_WEST => 0x2, + BlockFace.WEST_SOUTH_WEST => 0x3, + BlockFace.WEST => 0x4, + BlockFace.WEST_NORTH_WEST => 0x5, + BlockFace.NORTH_WEST => 0x6, + BlockFace.NORTH_NORTH_WEST => 0x7, + BlockFace.NORTH => 0x8, + BlockFace.NORTH_NORTH_EAST => 0x9, + BlockFace.NORTH_EAST => 0xA, + BlockFace.EAST_NORTH_EAST => 0xB, + BlockFace.EAST => 0xC, + BlockFace.EAST_SOUTH_EAST => 0xD, + BlockFace.SOUTH_SOUTH_EAST => 0xF, + _ => 0xE // SOUTH_EAST/default + }); + + setData(data); + } + + public override string ToString() + { + return $"{base.ToString()} facing {getFacing()}"; + } + +} \ No newline at end of file