diff --git a/src/main/java/com/minelittlepony/unicopia/block/ItemJarBlock.java b/src/main/java/com/minelittlepony/unicopia/block/ItemJarBlock.java index 68c9b9ba..1c726165 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/ItemJarBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/ItemJarBlock.java @@ -2,18 +2,38 @@ package com.minelittlepony.unicopia.block; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import java.util.stream.IntStream; +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.mixin.MixinEntityBucketItem; +import com.minelittlepony.unicopia.util.NbtSerialisable; + import net.minecraft.block.BlockEntityProvider; import net.minecraft.block.BlockRenderType; import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; import net.minecraft.block.InventoryProvider; import net.minecraft.block.entity.BlockEntity; +import net.minecraft.entity.Bucketable; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.SidedInventory; import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtElement; +import net.minecraft.network.listener.ClientPlayPacketListener; +import net.minecraft.network.packet.Packet; +import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket; +import net.minecraft.registry.Registries; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; +import net.minecraft.util.Identifier; +import net.minecraft.util.TypedActionResult; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; @@ -36,14 +56,7 @@ public class ItemJarBlock extends JarBlock implements BlockEntityProvider, Inven if (hand == Hand.OFF_HAND) { return ActionResult.PASS; } - return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).map(data -> { - ItemStack stack = player.getStackInHand(hand); - if (stack.isEmpty()) { - return data.removeItem(world, pos); - } - - return data.insertItem(world, pos, player.isCreative() ? stack.copyWithCount(1) : stack.split(1)); - }).orElse(ActionResult.PASS); + return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).map(data -> data.interact(player, hand)).orElse(ActionResult.PASS); } @Deprecated @@ -51,9 +64,7 @@ public class ItemJarBlock extends JarBlock implements BlockEntityProvider, Inven public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { if (!moved && !state.isOf(newState.getBlock())) { world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).ifPresent(data -> { - data.getStacks().forEach(stack -> { - dropStack(world, pos, stack); - }); + data.getContents().onDestroyed(); }); } super.onStateReplaced(state, world, pos, newState, moved); @@ -66,7 +77,10 @@ public class ItemJarBlock extends JarBlock implements BlockEntityProvider, Inven @Override public int getComparatorOutput(BlockState state, World world, BlockPos pos) { - return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).map(data -> Math.min(16, data.getStacks().size())).orElse(0); + return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR) + .map(TileData::getItems) + .map(data -> Math.min(16, data.getStacks().size())) + .orElse(0); } @Deprecated @@ -85,34 +99,210 @@ public class ItemJarBlock extends JarBlock implements BlockEntityProvider, Inven @Override public SidedInventory getInventory(BlockState state, WorldAccess world, BlockPos pos) { - return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).orElse(null); + return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).map(TileData::getItems).orElse(null); } - public static class TileData extends BlockEntity implements SidedInventory { - private static final int[] SLOTS = IntStream.range(0, 16).toArray(); - private final List stacks = new ArrayList<>(); + public static class TileData extends BlockEntity { + + private JarContents contents = new ItemsJarContents(this); public TileData(BlockPos pos, BlockState state) { super(UBlockEntities.ITEM_JAR, pos, state); } - public ActionResult insertItem(World world, BlockPos pos, ItemStack stack) { - if (stacks.size() >= size()) { - return ActionResult.FAIL; - } - stacks.add(stack); - markDirty(); - - return ActionResult.SUCCESS; + public ActionResult interact(PlayerEntity player, Hand hand) { + TypedActionResult result = contents.interact(player, hand); + contents = result.getValue(); + return result.getResult(); } - public ActionResult removeItem(World world, BlockPos pos) { - if (stacks.isEmpty()) { - return ActionResult.FAIL; + public JarContents getContents() { + return contents; + } + + @Nullable + public ItemsJarContents getItems() { + return getContents() instanceof ItemsJarContents c ? c : null; + } + + @Nullable + public EntityJarContents getEntity() { + return getContents() instanceof EntityJarContents c ? c : null; + } + + @Override + public Packet toUpdatePacket() { + return BlockEntityUpdateS2CPacket.create(this); + } + + @Override + public NbtCompound toInitialChunkDataNbt() { + return createNbt(); + } + + @Override + public void markDirty() { + super.markDirty(); + if (getWorld() instanceof ServerWorld sw) { + sw.getChunkManager().markForUpdate(getPos()); } - dropStack(world, pos, stacks.remove(0)); + } + + @Override + public void readNbt(NbtCompound nbt) { + if (nbt.contains("items", NbtElement.COMPOUND_TYPE)) { + contents = new ItemsJarContents(this); + contents.fromNBT(nbt.getCompound("items")); + } else if (nbt.contains("entity", NbtElement.COMPOUND_TYPE)) { + contents = new EntityJarContents(this); + contents.fromNBT(nbt.getCompound("entity")); + } + } + + @Override + protected void writeNbt(NbtCompound nbt) { + var items = getItems(); + if (items != null) { + nbt.put("items", items.toNBT()); + } else if (getEntity() != null) { + nbt.put("entity", getEntity().toNBT()); + } + } + } + + + public interface JarContents extends NbtSerialisable { + TypedActionResult interact(PlayerEntity player, Hand hand); + + void onDestroyed(); + } + + public static class EntityJarContents implements JarContents { + @Nullable + private EntityType entityType; + @Nullable + private Entity renderEntity; + + private final TileData tile; + + public EntityJarContents(TileData tile) { + this(tile, null); + } + + public EntityJarContents(TileData tile, EntityType entityType) { + this.tile = tile; + this.entityType = entityType; + } + + @Nullable + public Entity getOrCreateEntity() { + if (entityType == null && tile.getWorld() != null) { + return null; + } + + if (renderEntity == null || renderEntity.getType() != entityType) { + renderEntity = entityType.create(tile.getWorld()); + } + return renderEntity; + } + + @Override + public TypedActionResult interact(PlayerEntity player, Hand hand) { + ItemStack stack = player.getStackInHand(hand); + if (stack.isOf(Items.BUCKET)) { + if (getOrCreateEntity() instanceof Bucketable bucketable) { + if (!player.isCreative()) { + stack.decrement(1); + if (stack.isEmpty()) { + player.setStackInHand(hand, bucketable.getBucketItem()); + } else { + player.giveItemStack(bucketable.getBucketItem()); + } + } + player.playSound(bucketable.getBucketFillSound(), 1, 1); + } + tile.markDirty(); + return TypedActionResult.success(new ItemsJarContents(tile)); + } + return TypedActionResult.pass(this); + } + + @Override + public void onDestroyed() { + tile.getWorld().setBlockState(tile.getPos(), Blocks.WATER.getDefaultState()); + Entity entity = getOrCreateEntity(); + if (entity != null) { + entity.refreshPositionAfterTeleport(tile.getPos().toCenterPos()); + tile.getWorld().spawnEntity(entity); + } + } + + @Override + public void toNBT(NbtCompound compound) { + compound.putString("entity", EntityType.getId(entityType).toString()); + } + + @Override + public void fromNBT(NbtCompound compound) { + entityType = Registries.ENTITY_TYPE.getOrEmpty(Identifier.tryParse(compound.getString("entity"))).orElse(null); + } + + } + + public static class ItemsJarContents implements JarContents, SidedInventory { + private static final int[] SLOTS = IntStream.range(0, 16).toArray(); + + private final TileData tile; + private List stacks = new ArrayList<>(); + + public ItemsJarContents(TileData tile) { + this.tile = tile; + } + + @Override + public TypedActionResult interact(PlayerEntity player, Hand hand) { + ItemStack handStack = player.getStackInHand(hand); + + if (handStack.isEmpty()) { + if (stacks.isEmpty()) { + return TypedActionResult.fail(this); + } + dropStack(tile.getWorld(), tile.getPos(), stacks.remove(0)); + markDirty(); + return TypedActionResult.success(this); + } + + if (stacks.isEmpty()) { + if (handStack.getItem() instanceof MixinEntityBucketItem bucket) { + if (!player.isCreative()) { + handStack.decrement(1); + if (handStack.isEmpty()) { + player.setStackInHand(hand, Items.BUCKET.getDefaultStack()); + } else { + player.giveItemStack(Items.BUCKET.getDefaultStack()); + } + } + + player.playSound(bucket.getEmptyingSound(), 1, 1); + markDirty(); + return TypedActionResult.success(new EntityJarContents(tile, bucket.getEntityType())); + } + } + + if (stacks.size() >= size()) { + return TypedActionResult.fail(this); + } + stacks.add(player.isCreative() ? handStack.copyWithCount(1) : handStack.split(1)); markDirty(); - return ActionResult.SUCCESS; + + return TypedActionResult.success(this); + } + + @Override + public void onDestroyed() { + stacks.forEach(stack -> { + dropStack(tile.getWorld(), tile.getPos(), stack); + }); } public List getStacks() { @@ -137,51 +327,42 @@ public class ItemJarBlock extends JarBlock implements BlockEntityProvider, Inven @Override public ItemStack removeStack(int slot, int amount) { if (slot < 0 || slot >= stacks.size()) { - try { - ItemStack stack = stacks.get(slot); - ItemStack removed = stack.split(1); - if (stack.isEmpty()) { - stacks.remove(slot); - } - return removed; - } finally { - markDirty(); - } + return ItemStack.EMPTY; + } + + try { + ItemStack stack = stacks.get(slot); + ItemStack removed = stack.split(1); + if (stack.isEmpty()) { + stacks.remove(slot); + } + return removed; + } finally { + markDirty(); } - return ItemStack.EMPTY; } @Override public ItemStack removeStack(int slot) { if (slot < 0 || slot >= stacks.size()) { - try { - return stacks.remove(slot); - } finally { - markDirty(); - } + return ItemStack.EMPTY; + } + + try { + return stacks.remove(slot); + } finally { + markDirty(); } - return ItemStack.EMPTY; } @Override public void setStack(int slot, ItemStack stack) { if (slot >= stacks.size()) { - if (stacks.size() >= size()) { - dropStack(getWorld(), getPos(), stack); - } else { - stacks.add(stack); - } + stacks.add(stack); } else { - ItemStack existing = stacks.get(slot); - if (!ItemStack.canCombine(existing, stack)) { - dropStack(getWorld(), getPos(), stack); - } else { - existing.setCount(existing.getCount() + stack.split(Math.max(0, existing.getMaxCount() - existing.getCount())).getCount()); - if (!stack.isEmpty()) { - dropStack(getWorld(), getPos(), stack); - } - } + stacks.set(slot, stack); } + markDirty(); } @Override @@ -202,15 +383,29 @@ public class ItemJarBlock extends JarBlock implements BlockEntityProvider, Inven @Override public boolean canInsert(int slot, ItemStack stack, Direction dir) { - return (slot >= 0 && slot < size()) && (slot >= stacks.size() || ( - ItemStack.canCombine(stacks.get(slot), stack) - && (stacks.get(slot).getCount() + stack.getCount()) <= Math.min(stacks.get(slot).getMaxCount(), stack.getMaxCount()) - )); + return slot >= 0 && slot < size() && slot >= stacks.size(); } @Override public boolean canExtract(int slot, ItemStack stack, Direction dir) { - return true; + return slot >= 0 && slot < size() && slot < stacks.size(); + } + + @Override + public void toNBT(NbtCompound compound) { + compound.put("items", NbtSerialisable.ITEM_STACK.writeAll(stacks)); + } + + @Override + public void fromNBT(NbtCompound compound) { + stacks = NbtSerialisable.ITEM_STACK.readAll(compound.getList("items", NbtElement.COMPOUND_TYPE)) + .limit(size()) + .collect(Collectors.toList()); + } + + @Override + public void markDirty() { + tile.markDirty(); } } } diff --git a/src/main/java/com/minelittlepony/unicopia/block/JarBlock.java b/src/main/java/com/minelittlepony/unicopia/block/JarBlock.java index 80f24c7e..2bf5777b 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/JarBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/JarBlock.java @@ -11,10 +11,17 @@ import net.minecraft.block.AbstractGlassBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.ShapeContext; +import net.minecraft.block.Waterloggable; import net.minecraft.block.entity.BlockEntity; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.fluid.FluidState; +import net.minecraft.fluid.Fluids; +import net.minecraft.item.ItemPlacementContext; import net.minecraft.item.ItemStack; +import net.minecraft.state.StateManager; +import net.minecraft.state.property.BooleanProperty; +import net.minecraft.state.property.Properties; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.random.Random; @@ -22,17 +29,25 @@ import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.BlockView; import net.minecraft.world.World; +import net.minecraft.world.WorldAccess; import net.minecraft.world.explosion.Explosion; -public class JarBlock extends AbstractGlassBlock { +public class JarBlock extends AbstractGlassBlock implements Waterloggable { private static final VoxelShape SHAPE = VoxelShapes.union( Block.createCuboidShape(4, 0, 4, 12, 12, 12), Block.createCuboidShape(6, 12, 6, 10, 16, 10), Block.createCuboidShape(5, 13, 5, 11, 14, 11) ); + private static final BooleanProperty WATERLOGGED = Properties.WATERLOGGED; public JarBlock(Settings settings) { super(settings); + setDefaultState(getDefaultState().with(WATERLOGGED, false)); + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + builder.add(WATERLOGGED); } @Override @@ -40,9 +55,26 @@ public class JarBlock extends AbstractGlassBlock { return SHAPE; } + @Deprecated @Override - public boolean isSideInvisible(BlockState state, BlockState stateFrom, Direction direction) { - return super.isSideInvisible(state, stateFrom, direction); + public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) { + if (state.get(WATERLOGGED)) { + world.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world)); + } + + return super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos); + } + + @Nullable + @Override + public BlockState getPlacementState(ItemPlacementContext ctx) { + return getDefaultState().with(WATERLOGGED, ctx.getWorld().getFluidState(ctx.getBlockPos()).getFluid() == Fluids.WATER); + } + + @Deprecated + @Override + public FluidState getFluidState(BlockState state) { + return state.get(WATERLOGGED) ? Fluids.WATER.getStill(false) : super.getFluidState(state); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/RenderUtil.java b/src/main/java/com/minelittlepony/unicopia/client/render/RenderUtil.java index cb43a128..c2795b11 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/RenderUtil.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/RenderUtil.java @@ -5,10 +5,16 @@ import org.joml.Vector3f; import org.joml.Vector4f; import net.minecraft.client.render.BufferBuilder; +import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.VertexFormat; import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.texture.Sprite; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.math.ColorHelper; +import net.minecraft.util.math.Direction; public class RenderUtil { public static final Vector4f TEMP_VECTOR = new Vector4f(); @@ -25,6 +31,72 @@ public class RenderUtil { new Vertex(1, 0, 0, 1, 1), new Vertex(0, 0, 0, 0, 1) }; + private static final Vertex[][] CUBE_VERTICES = { + new Vertex[] { // down + new Vertex(0, 0, 0, 0, 0), + new Vertex(1, 0, 0, 1, 0), + new Vertex(1, 0, 1, 1, 1), + new Vertex(0, 0, 1, 0, 1) + }, + new Vertex[] { //up + new Vertex(0, 1, 0, 0, 0), + new Vertex(0, 1, 1, 0, 1), + new Vertex(1, 1, 1, 1, 1), + new Vertex(1, 1, 0, 1, 0) + }, + new Vertex[] { //north + new Vertex(0, 0, 0, 0, 0), + new Vertex(0, 1, 0, 0, 1), + new Vertex(1, 1, 0, 1, 1), + new Vertex(1, 0, 0, 1, 0) + }, + new Vertex[] { //south + new Vertex(0, 0, 1, 0, 0), + new Vertex(1, 0, 1, 1, 0), + new Vertex(1, 1, 1, 1, 1), + new Vertex(0, 1, 1, 0, 1) + }, + new Vertex[] { //west + new Vertex(0, 0, 0, 0, 0), + new Vertex(0, 0, 1, 1, 0), + new Vertex(0, 1, 1, 1, 1), + new Vertex(0, 1, 0, 0, 1) + }, + new Vertex[] { //east + new Vertex(1, 0, 0, 0, 0), + new Vertex(1, 1, 0, 1, 0), + new Vertex(1, 1, 1, 1, 1), + new Vertex(1, 0, 1, 0, 1) + } + }; + + public static void renderSpriteCubeFaces(MatrixStack matrices, VertexConsumerProvider provider, Sprite sprite, + float width, float height, float length, + int color, int light, int overlay, + Direction... directions) { + float r = ColorHelper.Abgr.getRed(color), + g = ColorHelper.Abgr.getGreen(color), + b = ColorHelper.Abgr.getBlue(color), + a = ColorHelper.Abgr.getAlpha(color); + float u0 = sprite.getMinU(), uDelta = sprite.getMaxU() - u0; + float v0 = sprite.getMinV(), vDelta = sprite.getMaxV() - v0; + RenderLayer layer = RenderLayer.getEntitySolid(sprite.getAtlasId()); + VertexConsumer buffer = provider.getBuffer(layer); + Matrix4f position = matrices.peek().getPositionMatrix(); + for (Direction direction : directions) { + for (Vertex vertex : CUBE_VERTICES[direction.ordinal()]) { + Vector4f pos = position.transform(TEMP_VECTOR.set(vertex.position(), 1).mul(width, height, length, 1)); + buffer.vertex( + pos.x, pos.y, pos.z, + r, g, b, a, + u0 + vertex.texture().x * uDelta, + v0 + vertex.texture().y * vDelta, + overlay, light, + direction.getOffsetX(), direction.getOffsetY(), direction.getOffsetZ() + ); + } + } + } public static void renderFace(MatrixStack matrices, Tessellator te, BufferBuilder buffer, float r, float g, float b, float a, int light) { renderFace(matrices, te, buffer, r, g, b, a, light, 1, 1); diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/entity/ItemJarBlockEntityRenderer.java b/src/main/java/com/minelittlepony/unicopia/client/render/entity/ItemJarBlockEntityRenderer.java index 85bec08a..e0b4883c 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/entity/ItemJarBlockEntityRenderer.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/entity/ItemJarBlockEntityRenderer.java @@ -1,29 +1,61 @@ package com.minelittlepony.unicopia.client.render.entity; -import java.util.List; - import com.minelittlepony.unicopia.block.ItemJarBlock; +import com.minelittlepony.unicopia.block.ItemJarBlock.EntityJarContents; +import com.minelittlepony.unicopia.block.ItemJarBlock.ItemsJarContents; +import com.minelittlepony.unicopia.client.render.RenderUtil; +import com.minelittlepony.unicopia.util.PosHelper; +import net.minecraft.block.Blocks; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.color.world.BiomeColors; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.block.entity.BlockEntityRenderer; import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; +import net.minecraft.client.render.entity.EntityRenderDispatcher; +import net.minecraft.client.render.item.ItemRenderer; import net.minecraft.client.render.model.json.ModelTransformationMode; +import net.minecraft.client.texture.Sprite; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.command.argument.EntityAnchorArgumentType.EntityAnchor; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.RotationAxis; +import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.random.Random; +import net.minecraft.world.World; public class ItemJarBlockEntityRenderer implements BlockEntityRenderer { + private final ItemRenderer itemRenderer; + private final EntityRenderDispatcher dispatcher; + + private final Sprite waterSprite; + public ItemJarBlockEntityRenderer(BlockEntityRendererFactory.Context ctx) { + itemRenderer = ctx.getItemRenderer(); + dispatcher = ctx.getEntityRenderDispatcher(); + waterSprite = MinecraftClient.getInstance().getBakedModelManager().getBlockModels().getModel(Blocks.WATER.getDefaultState()).getParticleSprite(); } @Override - public void render(ItemJarBlock.TileData entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertices, int light, int overlay) { + public void render(ItemJarBlock.TileData data, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertices, int light, int overlay) { - List stacks = entity.getStacks(); + ItemsJarContents items = data.getItems(); + if (items != null) { + renderItemStacks(data, items, tickDelta, matrices, vertices, light, overlay); + } + EntityJarContents entity = data.getEntity(); + if (entity != null) { + renderEntity(data, entity, tickDelta, matrices, vertices, light, overlay); + } + } + + private void renderItemStacks(ItemJarBlock.TileData data, ItemsJarContents items, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertices, int light, int overlay) { float itemScale = 0.35F; matrices.push(); @@ -31,19 +63,66 @@ public class ItemJarBlockEntityRenderer implements BlockEntityRenderer getEntityType(); + @Accessor + SoundEvent getEmptyingSound(); +} diff --git a/src/main/java/com/minelittlepony/unicopia/util/NbtSerialisable.java b/src/main/java/com/minelittlepony/unicopia/util/NbtSerialisable.java index 819153e5..54093f51 100644 --- a/src/main/java/com/minelittlepony/unicopia/util/NbtSerialisable.java +++ b/src/main/java/com/minelittlepony/unicopia/util/NbtSerialisable.java @@ -8,12 +8,14 @@ import java.util.stream.Stream; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; +import net.minecraft.item.ItemStack; import net.minecraft.nbt.*; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; public interface NbtSerialisable { Serializer BLOCK_POS = Serializer.of(NbtHelper::toBlockPos, NbtHelper::fromBlockPos); + Serializer ITEM_STACK = Serializer.of(ItemStack::fromNbt, stack -> stack.writeNbt(new NbtCompound())); /** * Called to save this to nbt to persist state on file or to transmit over the network @@ -44,6 +46,7 @@ public interface NbtSerialisable { } static Vec3d readVector(NbtList list) { + return new Vec3d(list.getDouble(0), list.getDouble(1), list.getDouble(2)); } diff --git a/src/main/java/com/minelittlepony/unicopia/util/PosHelper.java b/src/main/java/com/minelittlepony/unicopia/util/PosHelper.java index 7e203abd..2cb644e4 100644 --- a/src/main/java/com/minelittlepony/unicopia/util/PosHelper.java +++ b/src/main/java/com/minelittlepony/unicopia/util/PosHelper.java @@ -21,7 +21,7 @@ import net.minecraft.world.BlockView; import net.minecraft.world.World; public interface PosHelper { - + Direction[] ALL = Direction.values(); Direction[] HORIZONTAL = Arrays.stream(Direction.values()).filter(d -> d.getAxis().isHorizontal()).toArray(Direction[]::new); static Vec3d offset(Vec3d a, Vec3i b) { diff --git a/src/main/resources/unicopia.mixin.json b/src/main/resources/unicopia.mixin.json index 0a82eae8..855a75b7 100644 --- a/src/main/resources/unicopia.mixin.json +++ b/src/main/resources/unicopia.mixin.json @@ -19,6 +19,7 @@ "MixinEnchantmentHelper", "MixinFallLocation", "MixinEntity", + "MixinEntityBucketItem", "MixinEntityView", "MixinEntityShapeContext", "MixinFallingBlock",