Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package io.github.thatrobin.obscurum.block_entities;
- import io.github.thatrobin.obscurum.Obscurum;
- import io.github.thatrobin.obscurum.block.PlinthBlock;
- import net.minecraft.block.Block;
- import net.minecraft.block.BlockState;
- import net.minecraft.block.entity.BlockEntity;
- import net.minecraft.entity.player.PlayerEntity;
- import net.minecraft.inventory.Inventories;
- import net.minecraft.inventory.Inventory;
- import net.minecraft.item.ItemStack;
- import net.minecraft.nbt.NbtCompound;
- import net.minecraft.nbt.NbtElement;
- import net.minecraft.nbt.NbtList;
- import net.minecraft.network.listener.ClientPlayPacketListener;
- import net.minecraft.network.packet.Packet;
- import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket;
- import net.minecraft.util.collection.DefaultedList;
- import net.minecraft.util.math.BlockPos;
- import net.minecraft.util.math.Vec3d;
- import net.minecraft.world.World;
- import org.jetbrains.annotations.Nullable;
- import org.joml.Math;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Objects;
- public class PlinthBlockEntity extends BlockEntity implements Inventory {
- public static final int MAX_TRANSFER_TIME = 20;
- private static final int SLOT_SIZE = 64;
- private final DefaultedList<ItemStack> items = DefaultedList.ofSize(1, ItemStack.EMPTY); // 1 slot inventory for input buffer
- private final List<ItemTransfer> transferringItems = new ArrayList<>(); // Track items in transit
- private float transferCooldown = 0f;
- private BlockPos linkedPos;
- public PlinthBlockEntity(BlockPos pos, BlockState state) {
- super(ModBlockEntities.AMETHYST_PLINTH_BLOCK_ENTITY, pos, state);
- }
- public static void tick(World world, BlockPos pos, BlockState state, PlinthBlockEntity entity) {
- if(state.contains(PlinthBlock.TRANSFER_DIRECTION) && state.get(PlinthBlock.TRANSFER_DIRECTION)) {
- entity.updateTransfers();
- entity.tryStartNewTransfer();
- }
- entity.markDirty();
- }
- public static Vec3d lerpBlockPos(Vec3d start, Vec3d end, double progress) {
- // Interpolate each coordinate
- double x = Math.lerp(start.getX(), Math.abs(end.getX()), progress);
- double y = Math.lerp(start.getY(), Math.abs(end.getY()), progress);
- double z = Math.lerp(start.getZ(), Math.abs(end.getZ()), progress);
- if(end.getX() < 0) x *= -1;
- if(end.getY() < 0) y *= -1;
- if(end.getZ() < 0) z *= -1;
- // Create and return a new BlockPos
- return new Vec3d(x, y, z);
- }
- // Update ongoing transfers
- private void updateTransfers() {
- if (!transferringItems.isEmpty()) {
- Iterator<ItemTransfer> iterator = transferringItems.iterator();
- while (iterator.hasNext()) {
- ItemTransfer transfer = iterator.next();
- transfer.progress++;
- if (transfer.progress >= this.getTravelTime()) {
- transferItem(transfer.item); // Complete the transfer
- iterator.remove(); // Remove finished transfer
- }
- }
- }
- }
- // Try starting new transfers if there is space in the output buffer
- private void tryStartNewTransfer() {
- transferCooldown++;
- if (!this.isEmpty()) {
- float transferMaxCooldown = 10f;
- if(transferCooldown >= transferMaxCooldown) {
- PlinthBlockEntity linkedEntity = getLinkedEntity();
- if (linkedEntity != null && linkedEntity.hasSpaceInBuffer()) {
- ItemStack itemStack = this.removeStack(0, 1); // Remove one item from input buffer
- transferringItems.add(new ItemTransfer(itemStack, 0)); // Add to transferring list
- }
- transferCooldown = 0f;
- }
- }
- }
- public double getTravelTime() {
- return MAX_TRANSFER_TIME * this.getPos().toCenterPos().distanceTo(this.linkedPos.toCenterPos());
- }
- private void transferItem(ItemStack itemStack) {
- PlinthBlockEntity linkedEntity = getLinkedEntity();
- if (linkedEntity != null) {
- linkedEntity.addItemToBuffer(itemStack); // Transfer to output buffer
- }
- }
- @Override
- public NbtCompound toInitialChunkDataNbt() {
- NbtCompound nbt = super.toInitialChunkDataNbt();
- writeNbt(nbt);
- return nbt;
- }
- @Override
- public Packet<ClientPlayPacketListener> toUpdatePacket() {
- return BlockEntityUpdateS2CPacket.create(this);
- }
- @Nullable
- private PlinthBlockEntity getLinkedEntity() {
- if (this.linkedPos == null) {
- return null;
- }
- BlockEntity blockEntity = world.getBlockEntity(this.linkedPos);
- if (blockEntity instanceof PlinthBlockEntity) {
- return (PlinthBlockEntity) blockEntity;
- }
- return null;
- }
- public void addItemToBuffer(ItemStack stack) {
- ItemStack existingStack = this.getStack(0);
- if (existingStack.isEmpty()) {
- this.setStack(0, stack);
- } else if (ItemStack.canCombine(existingStack, stack)) {
- existingStack.increment(stack.getCount());
- }
- }
- public boolean hasItemInBuffer() {
- return !this.getStack(0).isEmpty();
- }
- private boolean hasSpaceInBuffer() {
- ItemStack stack = this.getStack(0);
- return stack.isEmpty() || stack.getCount() < SLOT_SIZE;
- }
- public List<ItemTransfer> getTransferringItems() {
- return transferringItems;
- }
- public BlockPos getLinkedPos() {
- return this.linkedPos;
- }
- public void setLinkedPos(BlockPos linkedPos, boolean setInner) {
- this.linkedPos = linkedPos;
- if (setInner) {
- PlinthBlockEntity linkedEntity = getLinkedEntity();
- if (linkedEntity != null) {
- linkedEntity.setLinkedPos(this.getPos(), false);
- }
- }
- }
- public static class ItemTransfer {
- public ItemStack item;
- public int progress;
- public ItemTransfer(ItemStack item, int progress) {
- this.item = item;
- this.progress = progress;
- }
- }
- @Override
- public int size() {
- return items.size();
- }
- @Override
- public boolean isEmpty() {
- return items.get(0).isEmpty();
- }
- @Override
- public ItemStack getStack(int slot) {
- return items.get(slot);
- }
- @Override
- public ItemStack removeStack(int slot, int amount) {
- ItemStack removedStack = Inventories.splitStack(items, slot, amount);
- if (removedStack.isEmpty()) {
- setStack(slot, ItemStack.EMPTY);
- }
- return removedStack;
- }
- @Override
- public ItemStack removeStack(int slot) {
- return Inventories.removeStack(items, slot);
- }
- @Override
- public void setStack(int slot, ItemStack stack) {
- items.set(slot, stack);
- if (stack.getCount() > SLOT_SIZE) {
- stack.setCount(SLOT_SIZE);
- }
- }
- @Override
- public void markDirty() {
- super.markDirty();
- if (world != null) {
- world.updateListeners(getPos(), getCachedState(), getCachedState(), Block.NOTIFY_LISTENERS);
- }
- }
- @Override
- public boolean canPlayerUse(PlayerEntity player) {
- return true;
- }
- @Override
- public void clear() {
- items.clear();
- }
- // Serialize block entity data to NBT
- @Override
- public void writeNbt(NbtCompound nbt) {
- super.writeNbt(nbt);
- Inventories.writeNbt(nbt, this.items);
- NbtList transferringList = new NbtList();
- for (ItemTransfer transfer : this.transferringItems) {
- NbtCompound transferNbt = new NbtCompound();
- transferNbt.put("Item", transfer.item.writeNbt(new NbtCompound()));
- transferNbt.putInt("Progress", transfer.progress);
- transferringList.add(transferNbt);
- }
- nbt.put("TransferringItems", transferringList);
- nbt.putFloat("TransferCooldown", transferCooldown);
- if (this.linkedPos != null) {
- nbt.putLong("LinkedPos", this.linkedPos.asLong());
- }
- }
- @Override
- public void readNbt(NbtCompound nbt) {
- super.readNbt(nbt);
- Inventories.readNbt(nbt, this.items);
- this.transferringItems.clear();
- NbtList transferringList = nbt.getList("TransferringItems", NbtElement.COMPOUND_TYPE);
- for (NbtElement element : transferringList) {
- NbtCompound transferNbt = (NbtCompound) element;
- ItemStack itemStack = ItemStack.fromNbt(transferNbt.getCompound("Item"));
- int progress = transferNbt.getInt("Progress");
- this.transferringItems.add(new ItemTransfer(itemStack, progress));
- }
- this.transferCooldown = nbt.getFloat("TransferCooldown");
- if (nbt.contains("LinkedPos")) {
- this.linkedPos = BlockPos.fromLong(nbt.getLong("LinkedPos"));
- }
- }
- }
Add Comment
Please, Sign In to add comment