diff --git a/src/main/java/net/minestom/server/entity/type/EntityItemFrame.java b/src/main/java/net/minestom/server/entity/type/EntityItemFrame.java new file mode 100644 index 000000000..79155e424 --- /dev/null +++ b/src/main/java/net/minestom/server/entity/type/EntityItemFrame.java @@ -0,0 +1,100 @@ +package net.minestom.server.entity.type; + +import net.minestom.server.entity.EntityType; +import net.minestom.server.entity.ObjectEntity; +import net.minestom.server.item.ItemStack; +import net.minestom.server.network.packet.PacketWriter; +import net.minestom.server.utils.Position; +import net.minestom.server.utils.Rotation; +import net.minestom.server.utils.item.ItemStackUtils; + +import java.util.function.Consumer; + +// FIXME: https://wiki.vg/Object_Data#Item_Frame_.28id_71.29 +// "You have to set both Orientation and Yaw/Pitch accordingly, otherwise it will not work." +public class EntityItemFrame extends ObjectEntity { + + private ItemFrameOrientation orientation; + private ItemStack itemStack; + private Rotation rotation; + + public EntityItemFrame(Position spawnPosition, ItemFrameOrientation orientation) { + super(EntityType.ITEM_FRAME, spawnPosition); + this.orientation = orientation; + this.rotation = Rotation.NONE; + } + + @Override + public Consumer getMetadataConsumer() { + return packet -> { + super.getMetadataConsumer().accept(packet); + fillMetadataIndex(packet, 7); + fillMetadataIndex(packet, 8); + }; + } + + @Override + protected void fillMetadataIndex(PacketWriter packet, int index) { + super.fillMetadataIndex(packet, index); + if (index == 7) { + packet.writeByte((byte) 7); + packet.writeByte(METADATA_SLOT); + packet.writeItemStack(ItemStackUtils.notNull(itemStack)); + } else if (index == 8) { + packet.writeByte((byte) 8); + packet.writeByte(METADATA_VARINT); + packet.writeVarInt(rotation.ordinal()); + } + } + + @Override + public int getObjectData() { + return orientation.ordinal(); + } + + /** + * Get the item stack in the frame + * + * @return the item stack in the frame + */ + public ItemStack getItemStack() { + return itemStack; + } + + /** + * Change the item stack in the frame + * + * @param itemStack the new item stack in the frame + */ + public void setItemStack(ItemStack itemStack) { + this.itemStack = itemStack; + sendMetadataIndex(7); + } + + /** + * Get the item rotation + * + * @return the item rotation + */ + public Rotation getRotation() { + return rotation; + } + + /** + * Change the item rotation + * + * @param rotation the new item rotation + */ + public void setRotation(Rotation rotation) { + this.rotation = rotation; + sendMetadataIndex(8); + } + + /** + * Represent the orientation of the frame + */ + public enum ItemFrameOrientation { + DOWN, UP, NORTH, SOUTH, WEST, EAST + } + +} diff --git a/src/main/java/net/minestom/server/utils/Rotation.java b/src/main/java/net/minestom/server/utils/Rotation.java new file mode 100644 index 000000000..dc06913b6 --- /dev/null +++ b/src/main/java/net/minestom/server/utils/Rotation.java @@ -0,0 +1,57 @@ +package net.minestom.server.utils; + +public enum Rotation { + + /** + * No rotation + */ + NONE, + /** + * Rotated clockwise by 45 degrees + */ + CLOCKWISE_45, + /** + * Rotated clockwise by 90 degrees + */ + CLOCKWISE, + /** + * Rotated clockwise by 135 degrees + */ + CLOCKWISE_135, + /** + * Flipped upside-down, a 180 degree rotation + */ + FLIPPED, + /** + * Flipped upside-down + 45 degree rotation + */ + FLIPPED_45, + /** + * Rotated counter-clockwise by 90 degrees + */ + COUNTER_CLOCKWISE, + /** + * Rotated counter-clockwise by 45 degrees + */ + COUNTER_CLOCKWISE_45; + + private static final Rotation[] rotations = values(); + + /** + * Rotate clockwise by 90 degrees. + * + * @return the relative rotation + */ + public Rotation rotateClockwise() { + return rotations[(this.ordinal() + 1) & 0x7]; + } + + /** + * Rotate counter-clockwise by 90 degrees. + * + * @return the relative rotation + */ + public Rotation rotateCounterClockwise() { + return rotations[(this.ordinal() - 1) & 0x7]; + } +}