Unicopia/src/main/java/com/minelittlepony/unicopia/block/ItemJarBlock.java

209 lines
7.9 KiB
Java
Raw Normal View History

2024-03-30 03:19:54 +01:00
package com.minelittlepony.unicopia.block;
import org.jetbrains.annotations.Nullable;
2024-03-31 23:34:31 +02:00
import com.minelittlepony.unicopia.block.jar.EntityJarContents;
import com.minelittlepony.unicopia.block.jar.FluidOnlyJarContents;
import com.minelittlepony.unicopia.block.jar.ItemsJarContents;
import com.mojang.serialization.MapCodec;
2024-03-31 23:34:31 +02:00
import com.minelittlepony.unicopia.block.jar.FakeFluidJarContents;
2024-03-31 23:34:31 +02:00
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidConstants;
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant;
2024-03-30 03:19:54 +01:00
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
import net.minecraft.block.InventoryProvider;
import net.minecraft.block.TransparentBlock;
2024-03-30 03:19:54 +01:00
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.SidedInventory;
import net.minecraft.item.ItemStack;
2024-03-31 23:34:31 +02:00
import net.minecraft.item.ItemUsage;
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;
2024-09-26 22:36:35 +02:00
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
import net.minecraft.server.world.ServerWorld;
2024-03-30 03:19:54 +01:00
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
2024-09-26 22:36:35 +02:00
import net.minecraft.util.ItemActionResult;
import net.minecraft.util.TypedActionResult;
2024-03-30 03:19:54 +01:00
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.WorldAccess;
public class ItemJarBlock extends JarBlock implements BlockEntityProvider, InventoryProvider {
public static final MapCodec<ItemJarBlock> CODEC = createCodec(ItemJarBlock::new);
2024-03-30 03:19:54 +01:00
public ItemJarBlock(Settings settings) {
super(settings);
}
@Override
protected MapCodec<? extends TransparentBlock> getCodec() {
return CODEC;
}
2024-03-30 03:19:54 +01:00
@Override
public BlockRenderType getRenderType(BlockState state) {
return BlockRenderType.MODEL;
}
@Override
2024-10-03 19:10:03 +02:00
protected ItemActionResult onUseWithItem(ItemStack stack, BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
2024-03-30 03:19:54 +01:00
if (hand == Hand.OFF_HAND) {
2024-09-26 22:36:35 +02:00
return ItemActionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
2024-03-30 03:19:54 +01:00
}
2024-09-26 22:36:35 +02:00
return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).map(data -> data.interact(player, hand)).orElse(ItemActionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION);
2024-03-30 03:19:54 +01:00
}
@Override
2024-10-03 19:10:03 +02:00
protected void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
2024-03-30 03:19:54 +01:00
if (!moved && !state.isOf(newState.getBlock())) {
world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).ifPresent(data -> {
data.getContents().onDestroyed();
2024-03-30 03:19:54 +01:00
});
}
super.onStateReplaced(state, world, pos, newState, moved);
}
@Override
2024-10-03 19:10:03 +02:00
protected boolean hasComparatorOutput(BlockState state) {
2024-03-30 03:19:54 +01:00
return true;
}
@Override
2024-10-03 19:10:03 +02:00
protected int getComparatorOutput(BlockState state, World world, BlockPos pos) {
return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR)
.map(TileData::getItems)
2024-03-31 23:34:31 +02:00
.map(data -> Math.min(16, data.stacks().size()))
.orElse(0);
2024-03-30 03:19:54 +01:00
}
@Override
2024-10-03 19:10:03 +02:00
protected boolean onSyncedBlockEvent(BlockState state, World world, BlockPos pos, int type, int data) {
2024-03-30 03:19:54 +01:00
super.onSyncedBlockEvent(state, world, pos, type, data);
BlockEntity blockEntity = world.getBlockEntity(pos);
return blockEntity != null && blockEntity.onSyncedBlockEvent(type, data);
}
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return new TileData(pos, state);
}
2024-03-31 23:34:31 +02:00
@Nullable
2024-03-30 03:19:54 +01:00
@Override
public SidedInventory getInventory(BlockState state, WorldAccess world, BlockPos pos) {
return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).map(TileData::getItems).orElse(null);
2024-03-30 03:19:54 +01:00
}
public static class TileData extends BlockEntity {
private JarContents contents = new ItemsJarContents(this);
2024-03-30 03:19:54 +01:00
public TileData(BlockPos pos, BlockState state) {
super(UBlockEntities.ITEM_JAR, pos, state);
}
2024-09-26 22:36:35 +02:00
public ItemActionResult interact(PlayerEntity player, Hand hand) {
TypedActionResult<JarContents> result = contents.interact(player, hand);
contents = result.getValue();
2024-09-26 22:36:35 +02:00
return result.getResult().isAccepted() ? ItemActionResult.SUCCESS : result.getResult() == ActionResult.FAIL ? ItemActionResult.FAIL : ItemActionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
}
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;
}
2024-03-31 23:34:31 +02:00
@Nullable
public FluidJarContents getFluid() {
return getContents() instanceof FluidJarContents c ? c : null;
}
@Nullable
public FakeFluidJarContents getFakeFluid() {
return getContents() instanceof FakeFluidJarContents c ? c : null;
}
@Override
public Packet<ClientPlayPacketListener> toUpdatePacket() {
return BlockEntityUpdateS2CPacket.create(this);
}
@Override
2024-09-26 22:36:35 +02:00
public NbtCompound toInitialChunkDataNbt(WrapperLookup lookup) {
return createNbt(lookup);
}
@Override
public void markDirty() {
super.markDirty();
if (getWorld() instanceof ServerWorld sw) {
sw.getChunkManager().markForUpdate(getPos());
2024-03-30 03:19:54 +01:00
}
}
2024-03-30 03:19:54 +01:00
@Override
2024-09-26 22:36:35 +02:00
public void readNbt(NbtCompound nbt, WrapperLookup lookup) {
if (nbt.contains("items", NbtElement.COMPOUND_TYPE)) {
2024-09-26 22:36:35 +02:00
contents = new ItemsJarContents(this, nbt.getCompound("items"), lookup);
} else if (nbt.contains("entity", NbtElement.COMPOUND_TYPE)) {
2024-03-31 23:34:31 +02:00
contents = new EntityJarContents(this, nbt.getCompound("entity"));
} else if (nbt.contains("fluid", NbtElement.COMPOUND_TYPE)) {
2024-10-03 19:10:03 +02:00
contents = new FluidOnlyJarContents(this, nbt.getCompound("fluid"), lookup);
2024-03-31 23:34:31 +02:00
} else if (nbt.contains("fakeFluid", NbtElement.COMPOUND_TYPE)) {
contents = new FakeFluidJarContents(this, nbt.getCompound("fakeFluid"));
}
2024-03-30 03:19:54 +01:00
}
@Override
2024-09-26 22:36:35 +02:00
protected void writeNbt(NbtCompound nbt, WrapperLookup lookup) {
var items = getItems();
if (items != null) {
2024-09-26 22:36:35 +02:00
nbt.put("items", items.toNBT(new NbtCompound(), lookup));
} else if (getEntity() != null) {
2024-09-26 22:36:35 +02:00
nbt.put("entity", getEntity().toNBT(new NbtCompound(), lookup));
2024-03-31 23:34:31 +02:00
} else if (getFluid() != null) {
2024-09-26 22:36:35 +02:00
nbt.put("fluid", getFluid().toNBT(new NbtCompound(), lookup));
2024-03-31 23:34:31 +02:00
} else if (getFakeFluid() != null) {
2024-09-28 23:27:46 +02:00
nbt.put("fakeFluid", getFakeFluid().toNBT(new NbtCompound(), lookup));
}
}
}
2024-03-31 23:34:31 +02:00
public interface JarContents {
TypedActionResult<JarContents> interact(PlayerEntity player, Hand hand);
void onDestroyed();
2024-09-26 22:36:35 +02:00
NbtCompound toNBT(NbtCompound compound, WrapperLookup lookup);
2024-03-31 23:34:31 +02:00
default void consumeAndSwap(PlayerEntity player, Hand hand, ItemStack output) {
player.setStackInHand(hand, ItemUsage.exchangeStack(player.getStackInHand(hand), player, output.copy()));
}
}
2024-03-31 23:34:31 +02:00
public interface FluidJarContents extends JarContents {
FluidVariant fluid();
2024-03-31 23:34:31 +02:00
default long amount() {
return FluidConstants.BUCKET;
2024-03-30 03:19:54 +01:00
}
}
}