Skip to content
11 changes: 11 additions & 0 deletions Minecraft.Server.FourKit/Material/Attachable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Minecraft.Server.FourKit.Block;
namespace Minecraft.Server.FourKit.material;

public interface Attachable : Directional
{
/// <summary>
/// Gets the face of the block to which this block is attached.
/// </summary>
/// <returns>A value of the BlockFace enumeration indicating the face of the attached block.</returns>
public BlockFace getAttachedFace();
}
101 changes: 101 additions & 0 deletions Minecraft.Server.FourKit/Material/Bed.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
namespace Minecraft.Server.FourKit.material;
using Minecraft.Server.FourKit.Block;
using Minecraft.Server.FourKit;

/// <summary>
/// Represents a bed
/// </summary>
public class Bed : MaterialData, Directional
{
/// <summary>
/// Default constructor for a bed
/// </summary>
public Bed() : base(Material.BED) { }

/// <summary>
/// Creates a bed facing the given direction.
/// </summary>
/// <param name="direction"> the direction the bed's head is facing</param>
public Bed(BlockFace direction) : this()
{
setFacingDirection(direction);
}

public Bed(int type) : base(type) { }

public Bed(Material type) : base(type) { }

public Bed(int type, byte data) : base(type, data) { }

public Bed(Material type, byte data) : base(type, data) { }

/// <summary>
/// Determines if this bed block is the head of the bed or not.
/// </summary>
/// <returns>true if this is the head of the bed, false if it is the foot.</returns>
public bool isHeadOfBed() => (getData() & 0x8) == 0x8;

/// <summary>
/// Configures this bed block to be either the head or foot of the bed.
/// </summary>
/// <param name="isHeadOfBed">true to make it the head</param>
public void setHeadOfBed(bool isHeadOfBed)
{
byte data = getData();
setData(isHeadOfBed ? (byte)(data | 0x8) : (byte)(data & 0x7)); //slightly different from the java implementation, to avoid replying on ~0x8 signed int behavior
}

/// <summary>
/// Set which direction of the head of the bed is facing. Note that this will
/// only affect one of the two blocks the bed is made of.
/// </summary>
/// <param name="face">Direction to point the head of the bed</param>
public void setFacingDirection(BlockFace face)
{
byte data = 0x3; //default to east, in case of invalid input

switch (face)
{
case BlockFace.SOUTH:
data = 0x0;
break;
case BlockFace.WEST:
data = 0x1;
break;
case BlockFace.NORTH:
data = 0x2;
break;
case BlockFace.EAST:
data = 0x3;
break;
}

if (isHeadOfBed())
{
data |= 0x8;
}

setData(data);
}

/// <summary>
/// Gets the direction that this block is currently facing.
/// </summary>
/// <returns>the direction the head of the bed is facing</returns>
public BlockFace getFacing()
{
byte data = (byte) (getData() & 0x7);

return data switch
{
0x0 => BlockFace.SOUTH,
0x1 => BlockFace.WEST,
0x2 => BlockFace.NORTH,
_ => BlockFace.EAST, //0x3 or default
};
}

public override string ToString() => (isHeadOfBed() ? "HEAD" : "FOOT") + " of " + base.ToString() + " facing " + getFacing();

public new Bed clone() => (Bed) base.clone();
}
81 changes: 81 additions & 0 deletions Minecraft.Server.FourKit/Material/Button.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
namespace Minecraft.Server.FourKit.material;
using Minecraft.Server.FourKit;
using Minecraft.Server.FourKit.Block;

public class Button : SimpleAttachableMaterialData, Redstone
{
public Button() : base(Material.STONE_BUTTON) { }
public Button(int type) : base(type) { }
public Button(Material type) : base(type) { }
public Button(int type, byte data) : base(type, data) { }
public Button(Material type, byte data) : base(type, data) { }

/// <summary>
/// Gets the current state of this Material, indicating if it's powered or unpowered
/// </summary>
/// <returns>true if powered, otherwise false</returns>
public bool isPowered()
{
return (getData() & 0x8) == 0x8;
}

/// <summary>
/// Sets the current state of this button
/// </summary>
/// <param name="isPowered">whether or not the button is powered</param>
public void setPowered(bool isPowered)
{
setData((byte)(isPowered ? (getData() | 0x8) : (getData() & ~0x8)));
}

/// <summary>
/// Gets the face that this block is attached on
/// </summary>
/// <returns>BlockFace attached to</returns>
public override BlockFace getAttachedFace()
{
byte data = (byte)(getData() & 0x7);

return data switch
{
0x1 => BlockFace.WEST,
0x2 => BlockFace.EAST,
0x3 => BlockFace.NORTH,
0x4 => BlockFace.SOUTH,
_ => BlockFace.NORTH //default to north, we cant return null
};
}

/// <summary>
/// Sets the direction this button is pointing toward
/// </summary>
/// <param name="face">Direction to face</param>
public override void setFacingDirection(BlockFace face)
{
byte data = (byte)(getData() & 0x8);

switch (face)
{
case BlockFace.EAST:
data |= 0x1;
break;

case BlockFace.WEST:
data |= 0x2;
break;

case BlockFace.SOUTH:
data |= 0x3;
break;

case BlockFace.NORTH:
data |= 0x4;
break;
}

setData(data);
}

public override string ToString() => base.ToString() + " " + (isPowered() ? "" : "NOT ") + "POWERED";
public new Button clone() => (Button) base.clone();
}
64 changes: 64 additions & 0 deletions Minecraft.Server.FourKit/Material/Cake.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
namespace Minecraft.Server.FourKit.material;
using Minecraft.Server.FourKit;

/// <summary>
/// Represents a cake
/// </summary>
public class Cake : MaterialData
{
public Cake() : base(Material.CAKE) { }
public Cake(int type) : base(type) { }
public Cake(Material type) : base(type) { }
public Cake(int type, byte data) : base(type, data) { }
public Cake(Material type, byte data) : base(type, data) { }

/// <summary>
/// Gets the number of slices eaten from this cake.
/// </summary>
/// <returns>the number of slices eaten</returns>
public int getSlicesEaten() => getData();

/// <summary>
/// Gets the number of slices remaining on this cake
/// </summary>
/// <returns>The number of slices remaining</returns>
public int getSlicesRemaining() => 6 - getData();


/// <summary>
/// Sets the number of slices eaten, capping the value at 6 if a higher value is provided. Values less than 0 are treated as 0.
/// </summary>
/// <param name="slicesEaten">the number of slices eaten</param>
public void setSlicesEaten(int slicesEaten)
{
if (slicesEaten < 0)
{
slicesEaten = 0;
}

if (slicesEaten < 6)
{
setData((byte)slicesEaten);
} //From bukkit: TODO: else destroy the block? Probably not possible though
}

/// <summary>
/// Sets the number of slices remaining, capping the value at 6 if a higher value is provided.
/// </summary>
/// <param name="slicesRemaining">The number of slices remaining. Values greater than 6 are treated as 6.</param>
public void setSlicesRemaining(int slicesRemaining)
{
if (slicesRemaining > 6)
{
slicesRemaining = 6;
}
if (slicesRemaining > 0)
{
setData((byte)(6 - slicesRemaining));
}//TODO: else destroy the block? Probably not possible though
}

public override string ToString() => $"{base.ToString()} {getSlicesEaten()}/{getSlicesRemaining()} slices eaten/remaining";

public new Cake clone() => (Cake)base.clone();
}
31 changes: 31 additions & 0 deletions Minecraft.Server.FourKit/Material/Cauldron.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
namespace Minecraft.Server.FourKit.material;
using Minecraft.Server.FourKit;

/// <summary>
/// Represents a Cauldron
/// </summary>
public class Cauldron : MaterialData
{
private static readonly int CAULDRON_FULL = 3;
private static readonly int CAULDRON_EMPTY = 0;

public Cauldron() : base(Material.CAULDRON) { }
public Cauldron(int type, byte data) : base(type, data) { }
public Cauldron(byte data) : base(Material.CAULDRON, data) { }

/// <summary>
/// Check if the cauldron is full
/// </summary>
/// <returns>true if it is full</returns>
public bool isFull() => getData() >= CAULDRON_FULL;

/// <summary>
/// Check if the cauldron is empty
/// </summary>
/// <returns>true if it is empty</returns>
public bool isEmpty() => getData() <= CAULDRON_EMPTY;

public override string ToString() => (isEmpty() ? "EMPTY" : (isFull() ? "FULL" : getData() + "/3 FULL")) + " CAULDRON";

public new Cauldron clone() => (Cauldron) base.clone();
}
27 changes: 27 additions & 0 deletions Minecraft.Server.FourKit/Material/Chest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace Minecraft.Server.FourKit.material;
using Minecraft.Server.FourKit;
using Minecraft.Server.FourKit.Block;

/// <summary>
/// Represents a chest
/// </summary>
public class Chest : DirectionalContainer
{
public Chest() : base(Material.CHEST) { }

/// <summary>
/// Instantiate a chest facing a particular direction.
/// </summary>
/// <param name="direction">the direction the chest's lid opens towards<param>
public Chest(BlockFace direction) : this()
{
setFacingDirection(direction);
}

public Chest(int type) : base(type) { }
public Chest(Material type) : base(type) { }
public Chest(int type, byte data) : base(type, data) { }
public Chest(Material type, byte data) : base(type, data) { }

public new Chest clone() => (Chest) base.clone();
}
Loading
Loading