Guest User

Untitled

a guest
Sep 7th, 2024
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 9.15 KB | None | 0 0
  1. package io.github.thatrobin.obscurum.block_entities;
  2.  
  3. import io.github.thatrobin.obscurum.Obscurum;
  4. import io.github.thatrobin.obscurum.block.PlinthBlock;
  5. import net.minecraft.block.Block;
  6. import net.minecraft.block.BlockState;
  7. import net.minecraft.block.entity.BlockEntity;
  8. import net.minecraft.entity.player.PlayerEntity;
  9. import net.minecraft.inventory.Inventories;
  10. import net.minecraft.inventory.Inventory;
  11. import net.minecraft.item.ItemStack;
  12. import net.minecraft.nbt.NbtCompound;
  13. import net.minecraft.nbt.NbtElement;
  14. import net.minecraft.nbt.NbtList;
  15. import net.minecraft.network.listener.ClientPlayPacketListener;
  16. import net.minecraft.network.packet.Packet;
  17. import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket;
  18. import net.minecraft.util.collection.DefaultedList;
  19. import net.minecraft.util.math.BlockPos;
  20. import net.minecraft.util.math.Vec3d;
  21. import net.minecraft.world.World;
  22. import org.jetbrains.annotations.Nullable;
  23. import org.joml.Math;
  24.  
  25. import java.util.ArrayList;
  26. import java.util.Iterator;
  27. import java.util.List;
  28. import java.util.Objects;
  29.  
  30. public class PlinthBlockEntity extends BlockEntity implements Inventory {
  31.  
  32.     public static final int MAX_TRANSFER_TIME = 20;
  33.     private static final int SLOT_SIZE = 64;
  34.  
  35.     private final DefaultedList<ItemStack> items = DefaultedList.ofSize(1, ItemStack.EMPTY); // 1 slot inventory for input buffer
  36.     private final List<ItemTransfer> transferringItems = new ArrayList<>(); // Track items in transit
  37.     private float transferCooldown = 0f;
  38.     private BlockPos linkedPos;
  39.  
  40.     public PlinthBlockEntity(BlockPos pos, BlockState state) {
  41.         super(ModBlockEntities.AMETHYST_PLINTH_BLOCK_ENTITY, pos, state);
  42.     }
  43.  
  44.     public static void tick(World world, BlockPos pos, BlockState state, PlinthBlockEntity entity) {
  45.         if(state.contains(PlinthBlock.TRANSFER_DIRECTION) && state.get(PlinthBlock.TRANSFER_DIRECTION)) {
  46.             entity.updateTransfers();
  47.  
  48.             entity.tryStartNewTransfer();
  49.  
  50.         }
  51.         entity.markDirty();
  52.     }
  53.  
  54.     public static Vec3d lerpBlockPos(Vec3d start, Vec3d end, double progress) {
  55.         // Interpolate each coordinate
  56.         double x = Math.lerp(start.getX(), Math.abs(end.getX()), progress);
  57.         double y = Math.lerp(start.getY(), Math.abs(end.getY()), progress);
  58.         double z = Math.lerp(start.getZ(), Math.abs(end.getZ()), progress);
  59.  
  60.         if(end.getX() < 0) x *= -1;
  61.         if(end.getY() < 0) y *= -1;
  62.         if(end.getZ() < 0) z *= -1;
  63.  
  64.         // Create and return a new BlockPos
  65.         return new Vec3d(x, y, z);
  66.     }
  67.  
  68.     // Update ongoing transfers
  69.     private void updateTransfers() {
  70.         if (!transferringItems.isEmpty()) {
  71.             Iterator<ItemTransfer> iterator = transferringItems.iterator();
  72.             while (iterator.hasNext()) {
  73.                 ItemTransfer transfer = iterator.next();
  74.                 transfer.progress++;
  75.                 if (transfer.progress >= this.getTravelTime()) {
  76.                     transferItem(transfer.item); // Complete the transfer
  77.                     iterator.remove(); // Remove finished transfer
  78.                 }
  79.             }
  80.         }
  81.     }
  82.  
  83.     // Try starting new transfers if there is space in the output buffer
  84.     private void tryStartNewTransfer() {
  85.         transferCooldown++;
  86.         if (!this.isEmpty()) {
  87.             float transferMaxCooldown = 10f;
  88.             if(transferCooldown >= transferMaxCooldown) {
  89.                 PlinthBlockEntity linkedEntity = getLinkedEntity();
  90.                 if (linkedEntity != null && linkedEntity.hasSpaceInBuffer()) {
  91.                     ItemStack itemStack = this.removeStack(0, 1); // Remove one item from input buffer
  92.                     transferringItems.add(new ItemTransfer(itemStack, 0)); // Add to transferring list
  93.                 }
  94.                 transferCooldown = 0f;
  95.             }
  96.         }
  97.     }
  98.  
  99.     public double getTravelTime() {
  100.         return MAX_TRANSFER_TIME * this.getPos().toCenterPos().distanceTo(this.linkedPos.toCenterPos());
  101.     }
  102.  
  103.     private void transferItem(ItemStack itemStack) {
  104.         PlinthBlockEntity linkedEntity = getLinkedEntity();
  105.         if (linkedEntity != null) {
  106.             linkedEntity.addItemToBuffer(itemStack); // Transfer to output buffer
  107.         }
  108.     }
  109.  
  110.     @Override
  111.     public NbtCompound toInitialChunkDataNbt() {
  112.         NbtCompound nbt = super.toInitialChunkDataNbt();
  113.         writeNbt(nbt);
  114.         return nbt;
  115.     }
  116.  
  117.     @Override
  118.     public Packet<ClientPlayPacketListener> toUpdatePacket() {
  119.         return BlockEntityUpdateS2CPacket.create(this);
  120.     }
  121.  
  122.     @Nullable
  123.     private PlinthBlockEntity getLinkedEntity() {
  124.         if (this.linkedPos == null) {
  125.             return null;
  126.         }
  127.  
  128.         BlockEntity blockEntity = world.getBlockEntity(this.linkedPos);
  129.         if (blockEntity instanceof PlinthBlockEntity) {
  130.             return (PlinthBlockEntity) blockEntity;
  131.         }
  132.  
  133.         return null;
  134.     }
  135.  
  136.     public void addItemToBuffer(ItemStack stack) {
  137.         ItemStack existingStack = this.getStack(0);
  138.         if (existingStack.isEmpty()) {
  139.             this.setStack(0, stack);
  140.         } else if (ItemStack.canCombine(existingStack, stack)) {
  141.             existingStack.increment(stack.getCount());
  142.         }
  143.  
  144.     }
  145.  
  146.     public boolean hasItemInBuffer() {
  147.         return !this.getStack(0).isEmpty();
  148.     }
  149.  
  150.     private boolean hasSpaceInBuffer() {
  151.         ItemStack stack = this.getStack(0);
  152.         return stack.isEmpty() || stack.getCount() < SLOT_SIZE;
  153.     }
  154.  
  155.     public List<ItemTransfer> getTransferringItems() {
  156.         return transferringItems;
  157.     }
  158.  
  159.     public BlockPos getLinkedPos() {
  160.         return this.linkedPos;
  161.     }
  162.  
  163.     public void setLinkedPos(BlockPos linkedPos, boolean setInner) {
  164.         this.linkedPos = linkedPos;
  165.         if (setInner) {
  166.             PlinthBlockEntity linkedEntity = getLinkedEntity();
  167.             if (linkedEntity != null) {
  168.                 linkedEntity.setLinkedPos(this.getPos(), false);
  169.             }
  170.         }
  171.     }
  172.  
  173.     public static class ItemTransfer {
  174.         public ItemStack item;
  175.         public int progress;
  176.  
  177.         public ItemTransfer(ItemStack item, int progress) {
  178.             this.item = item;
  179.             this.progress = progress;
  180.         }
  181.     }
  182.  
  183.     @Override
  184.     public int size() {
  185.         return items.size();
  186.     }
  187.  
  188.     @Override
  189.     public boolean isEmpty() {
  190.         return items.get(0).isEmpty();
  191.     }
  192.  
  193.     @Override
  194.     public ItemStack getStack(int slot) {
  195.         return items.get(slot);
  196.     }
  197.  
  198.     @Override
  199.     public ItemStack removeStack(int slot, int amount) {
  200.         ItemStack removedStack = Inventories.splitStack(items, slot, amount);
  201.         if (removedStack.isEmpty()) {
  202.             setStack(slot, ItemStack.EMPTY);
  203.         }
  204.         return removedStack;
  205.     }
  206.  
  207.     @Override
  208.     public ItemStack removeStack(int slot) {
  209.         return Inventories.removeStack(items, slot);
  210.     }
  211.  
  212.     @Override
  213.     public void setStack(int slot, ItemStack stack) {
  214.         items.set(slot, stack);
  215.         if (stack.getCount() > SLOT_SIZE) {
  216.             stack.setCount(SLOT_SIZE);
  217.         }
  218.     }
  219.  
  220.     @Override
  221.     public void markDirty() {
  222.         super.markDirty();
  223.         if (world != null) {
  224.             world.updateListeners(getPos(), getCachedState(), getCachedState(), Block.NOTIFY_LISTENERS);
  225.         }
  226.     }
  227.  
  228.     @Override
  229.     public boolean canPlayerUse(PlayerEntity player) {
  230.         return true;
  231.     }
  232.  
  233.     @Override
  234.     public void clear() {
  235.         items.clear();
  236.     }
  237.  
  238.     // Serialize block entity data to NBT
  239.     @Override
  240.     public void writeNbt(NbtCompound nbt) {
  241.         super.writeNbt(nbt);
  242.         Inventories.writeNbt(nbt, this.items);
  243.  
  244.         NbtList transferringList = new NbtList();
  245.         for (ItemTransfer transfer : this.transferringItems) {
  246.             NbtCompound transferNbt = new NbtCompound();
  247.             transferNbt.put("Item", transfer.item.writeNbt(new NbtCompound()));
  248.             transferNbt.putInt("Progress", transfer.progress);
  249.             transferringList.add(transferNbt);
  250.         }
  251.         nbt.put("TransferringItems", transferringList);
  252.         nbt.putFloat("TransferCooldown", transferCooldown);
  253.  
  254.         if (this.linkedPos != null) {
  255.             nbt.putLong("LinkedPos", this.linkedPos.asLong());
  256.         }
  257.     }
  258.  
  259.  
  260.     @Override
  261.     public void readNbt(NbtCompound nbt) {
  262.         super.readNbt(nbt);
  263.         Inventories.readNbt(nbt, this.items);
  264.         this.transferringItems.clear();
  265.         NbtList transferringList = nbt.getList("TransferringItems", NbtElement.COMPOUND_TYPE);
  266.         for (NbtElement element : transferringList) {
  267.             NbtCompound transferNbt = (NbtCompound) element;
  268.             ItemStack itemStack = ItemStack.fromNbt(transferNbt.getCompound("Item"));
  269.             int progress = transferNbt.getInt("Progress");
  270.             this.transferringItems.add(new ItemTransfer(itemStack, progress));
  271.         }
  272.         this.transferCooldown = nbt.getFloat("TransferCooldown");
  273.  
  274.         if (nbt.contains("LinkedPos")) {
  275.             this.linkedPos = BlockPos.fromLong(nbt.getLong("LinkedPos"));
  276.         }
  277.     }
  278.  
  279.  
  280. }
  281.  
Add Comment
Please, Sign In to add comment