2024-03-30 03:19:54 +01:00
|
|
|
package com.minelittlepony.unicopia.block;
|
|
|
|
|
2024-03-30 22:22:36 +01:00
|
|
|
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;
|
2024-04-05 23:01:26 +02:00
|
|
|
import com.mojang.serialization.MapCodec;
|
2024-03-31 23:34:31 +02:00
|
|
|
import com.minelittlepony.unicopia.block.jar.FakeFluidJarContents;
|
2024-03-30 22:22:36 +01:00
|
|
|
|
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;
|
2024-04-05 23:01:26 +02:00
|
|
|
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;
|
2024-03-30 22:22:36 +01:00
|
|
|
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;
|
2024-03-30 22:22:36 +01:00
|
|
|
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;
|
2024-03-30 22:22:36 +01:00
|
|
|
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 {
|
2024-04-05 23:01:26 +02:00
|
|
|
public static final MapCodec<ItemJarBlock> CODEC = createCodec(ItemJarBlock::new);
|
2024-03-30 03:19:54 +01:00
|
|
|
|
|
|
|
public ItemJarBlock(Settings settings) {
|
|
|
|
super(settings);
|
|
|
|
}
|
|
|
|
|
2024-04-05 23:01:26 +02:00
|
|
|
@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 -> {
|
2024-03-30 22:22:36 +01:00
|
|
|
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) {
|
2024-03-30 22:22:36 +01:00
|
|
|
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()))
|
2024-03-30 22:22:36 +01:00
|
|
|
.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) {
|
2024-03-30 22:22:36 +01:00
|
|
|
return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).map(TileData::getItems).orElse(null);
|
2024-03-30 03:19:54 +01:00
|
|
|
}
|
|
|
|
|
2024-03-30 22:22:36 +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) {
|
2024-03-30 22:22:36 +01:00
|
|
|
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;
|
2024-03-30 22:22:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2024-03-30 22:22:36 +01:00
|
|
|
@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);
|
2024-03-30 22:22:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@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 22:22:36 +01:00
|
|
|
}
|
2024-03-30 03:19:54 +01:00
|
|
|
|
2024-03-30 22:22:36 +01:00
|
|
|
@Override
|
2024-09-26 22:36:35 +02:00
|
|
|
public void readNbt(NbtCompound nbt, WrapperLookup lookup) {
|
2024-03-30 22:22:36 +01:00
|
|
|
if (nbt.contains("items", NbtElement.COMPOUND_TYPE)) {
|
2024-09-26 22:36:35 +02:00
|
|
|
contents = new ItemsJarContents(this, nbt.getCompound("items"), lookup);
|
2024-03-30 22:22:36 +01:00
|
|
|
} 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 22:22:36 +01:00
|
|
|
}
|
2024-03-30 03:19:54 +01:00
|
|
|
}
|
|
|
|
|
2024-03-30 22:22:36 +01:00
|
|
|
@Override
|
2024-09-26 22:36:35 +02:00
|
|
|
protected void writeNbt(NbtCompound nbt, WrapperLookup lookup) {
|
2024-03-30 22:22:36 +01:00
|
|
|
var items = getItems();
|
|
|
|
if (items != null) {
|
2024-09-26 22:36:35 +02:00
|
|
|
nbt.put("items", items.toNBT(new NbtCompound(), lookup));
|
2024-03-30 22:22:36 +01:00
|
|
|
} 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-30 22:22:36 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-31 23:34:31 +02:00
|
|
|
public interface JarContents {
|
2024-03-30 22:22:36 +01:00
|
|
|
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-30 22:22:36 +01:00
|
|
|
|
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-30 22:22:36 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-31 23:34:31 +02:00
|
|
|
public interface FluidJarContents extends JarContents {
|
|
|
|
FluidVariant fluid();
|
2024-03-30 22:22:36 +01:00
|
|
|
|
2024-03-31 23:34:31 +02:00
|
|
|
default long amount() {
|
|
|
|
return FluidConstants.BUCKET;
|
2024-03-30 03:19:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|