1
0
Fork 0

implement pipes

This commit is contained in:
Sen 2025-08-13 14:40:11 +02:00
parent 90c25e5fd7
commit 6e5a1b7e37
Signed by: sen
GPG key ID: 3AC50A6F47D1B722

View file

@ -10,545 +10,419 @@ import common.block.tech.BlockPipe;
import common.entity.Entity;
import common.entity.item.EntityItem;
import common.entity.npc.EntityNPC;
import common.entity.types.EntityLiving;
import common.inventory.IInventory;
import common.inventory.ISidedInventory;
import common.item.ItemStack;
import common.tags.TagObject;
import common.util.BlockPos;
import common.util.BoundingBox;
import common.util.ExtMath;
import common.util.Facing;
import common.vars.Vars;
import common.world.State;
import common.world.World;
public class TileEntityPipe extends TileEntity implements IInventory, ITickable
{
private ItemStack inventory = null;
private int cooldown = -1;
public void readTags(TagObject tag)
{
super.readTags(tag);
this.cooldown = tag.getInt("Cooldown");
this.inventory = ItemStack.readFromTag(tag.getObject("Item"));
}
public void writeTags(TagObject tag)
{
super.writeTags(tag);
tag.setInt("Cooldown", this.cooldown);
if (this.inventory != null)
{
TagObject item = new TagObject();
this.inventory.writeTags(item);
tag.setObject("Item", item);
}
}
public int getSizeInventory()
{
return 1;
}
public ItemStack getStackInSlot(int index)
{
return this.inventory;
}
public ItemStack decrStackSize(int index, int count)
{
if (this.inventory != null)
{
if (this.inventory.getSize() <= count)
{
ItemStack itemstack1 = this.inventory;
this.inventory = null;
return itemstack1;
}
else
{
ItemStack itemstack = this.inventory.split(count);
if (this.inventory.isEmpty())
{
this.inventory = null;
}
return itemstack;
}
}
else
{
return null;
}
}
public ItemStack removeStackFromSlot(int index)
{
if (this.inventory != null)
{
ItemStack itemstack = this.inventory;
this.inventory = null;
return itemstack;
}
else
{
return null;
}
}
public void setInventorySlotContents(int index, ItemStack stack)
{
this.inventory = stack;
}
public void clear()
{
this.inventory = null;
}
public boolean isUseableByPlayer(EntityNPC player)
{
return this.world.getTileEntity(this.pos) != this ? false : player.getDistanceSq((double)this.pos.getX() + 0.5D, (double)this.pos.getY() + 0.5D, (double)this.pos.getZ() + 0.5D) <= 64.0D;
}
public void update()
{
if (this.world != null && !this.world.client)
{
--this.cooldown;
if (!this.isOnTransferCooldown())
{
this.setTransferCooldown(0);
this.updatePipe();
}
}
}
public boolean updatePipe()
{
if (this.world != null && !this.world.client)
{
if (!this.isOnTransferCooldown())
{
State state = this.getState();
if(!(state.getBlock() instanceof BlockPipe) /* || !this.decrPower() */) // TODO: power
return false;
boolean flag = false;
if (!this.isEmpty())
{
flag = this.transferItemsOut();
}
if (!this.isFull())
{
flag = captureDroppedItems(this, state.getValue(BlockPipe.FACING) != Facing.UP) || flag;
}
if (flag)
{
this.setTransferCooldown(Vars.pipeDelay);
this.markDirty();
return true;
}
}
return false;
}
else
{
return false;
}
}
private boolean isEmpty()
{
return this.inventory == null;
}
private boolean isFull()
{
return this.inventory != null && this.inventory.isFull();
}
private boolean transferItemsOut()
{
IInventory iinventory = this.getInventoryForTransfer();
if (iinventory == null)
{
return false;
}
else
{
State state = this.getState();
Facing enumfacing = state.getBlock() instanceof BlockPipe ? state.getValue(BlockPipe.FACING).getOpposite() : Facing.DOWN;
if (isInventoryFull(iinventory, enumfacing))
{
return false;
}
else
{
for (int i = 0; i < this.getSizeInventory(); ++i)
{
if (this.getStackInSlot(i) != null)
{
ItemStack itemstack = this.getStackInSlot(i).copy();
ItemStack itemstack1 = putStackInInventoryAllSlots(iinventory, this.decrStackSize(i, 1), enumfacing);
if (itemstack1 == null || itemstack1.isEmpty())
{
iinventory.markDirty();
return true;
}
this.setInventorySlotContents(i, itemstack);
}
}
return false;
}
}
}
public static boolean isInventoryFull(IInventory inventoryIn, Facing side)
{
if (inventoryIn instanceof ISidedInventory)
{
ISidedInventory isidedinventory = (ISidedInventory)inventoryIn;
int[] aint = isidedinventory.getSlotsForFace(side);
for (int k = 0; k < aint.length; ++k)
{
ItemStack itemstack1 = isidedinventory.getStackInSlot(aint[k]);
if (itemstack1 == null || !itemstack1.isFull())
{
return false;
}
}
}
else
{
int i = inventoryIn.getSizeInventory();
for (int j = 0; j < i; ++j)
{
ItemStack itemstack = inventoryIn.getStackInSlot(j);
if (itemstack == null || !itemstack.isFull())
{
return false;
}
}
}
return true;
}
public static boolean isInventoryEmpty(IInventory inventoryIn, Facing side)
{
if (inventoryIn instanceof ISidedInventory)
{
ISidedInventory isidedinventory = (ISidedInventory)inventoryIn;
int[] aint = isidedinventory.getSlotsForFace(side);
for (int i = 0; i < aint.length; ++i)
{
if (isidedinventory.getStackInSlot(aint[i]) != null)
{
return false;
}
}
}
else
{
int j = inventoryIn.getSizeInventory();
for (int k = 0; k < j; ++k)
{
if (inventoryIn.getStackInSlot(k) != null)
{
return false;
}
}
}
return true;
}
public static boolean captureDroppedItems(TileEntityPipe te, boolean down)
{
IInventory iinventory = getPipeInventory(te, !down);
if (iinventory != null)
{
Facing enumfacing = down ? Facing.UP : Facing.DOWN;
if (isInventoryEmpty(iinventory, enumfacing))
{
return false;
}
if (iinventory instanceof ISidedInventory)
{
ISidedInventory isidedinventory = (ISidedInventory)iinventory;
int[] aint = isidedinventory.getSlotsForFace(enumfacing);
for (int i = 0; i < aint.length; ++i)
{
if (pullItemFromSlot(te, iinventory, aint[i], enumfacing))
{
return true;
}
}
}
else
{
int j = iinventory.getSizeInventory();
for (int k = 0; k < j; ++k)
{
if (pullItemFromSlot(te, iinventory, k, enumfacing))
{
return true;
}
}
}
}
else if(down)
{
for (EntityItem entityitem : findDroppedItems(te.getWorld(), te.getXPos(), te.getYPos() + 1.0D, te.getZPos()))
{
if (putDropInInventoryAllSlots(te, entityitem))
{
return true;
}
}
}
return false;
}
public static boolean pullItemFromSlot(TileEntityPipe pipe, IInventory inventoryIn, int index, Facing direction)
{
ItemStack itemstack = inventoryIn.getStackInSlot(index);
if (itemstack != null && canExtractItemFromSlot(inventoryIn, itemstack, index, direction))
{
ItemStack itemstack1 = itemstack.copy();
ItemStack itemstack2 = putStackInInventoryAllSlots(pipe, inventoryIn.decrStackSize(index, 1), (Facing)null);
if (itemstack2 == null || itemstack2.isEmpty())
{
inventoryIn.markDirty();
return true;
}
inventoryIn.setInventorySlotContents(index, itemstack1);
}
return false;
}
public static boolean putDropInInventoryAllSlots(IInventory p_145898_0_, EntityItem itemIn)
{
boolean flag = false;
if (itemIn == null)
{
return false;
}
else
{
ItemStack itemstack = itemIn.getEntityItem().copy();
ItemStack itemstack1 = putStackInInventoryAllSlots(p_145898_0_, itemstack, (Facing)null);
if (itemstack1 != null && !itemstack1.isEmpty())
{
itemIn.setEntityItemStack(itemstack1);
}
else
{
flag = true;
itemIn.setDead();
}
return flag;
}
}
public static ItemStack putStackInInventoryAllSlots(IInventory inventoryIn, ItemStack stack, Facing side)
{
if (inventoryIn instanceof ISidedInventory && side != null)
{
ISidedInventory isidedinventory = (ISidedInventory)inventoryIn;
int[] aint = isidedinventory.getSlotsForFace(side);
for (int k = 0; k < aint.length && stack != null && !stack.isEmpty(); ++k)
{
stack = insertStack(inventoryIn, stack, aint[k], side);
}
}
else
{
int i = inventoryIn.getSizeInventory();
for (int j = 0; j < i && stack != null && !stack.isEmpty(); ++j)
{
stack = insertStack(inventoryIn, stack, j, side);
}
}
if (stack != null && stack.isEmpty())
{
stack = null;
}
return stack;
}
public static boolean canInsertItemInSlot(IInventory inventoryIn, ItemStack stack, int index, Facing side)
{
return !inventoryIn.isItemValidForSlot(index, stack) ? false : !(inventoryIn instanceof ISidedInventory) || ((ISidedInventory)inventoryIn).canInsertItem(index, stack, side);
}
public static boolean canExtractItemFromSlot(IInventory inventoryIn, ItemStack stack, int index, Facing side)
{
return !(inventoryIn instanceof ISidedInventory) || ((ISidedInventory)inventoryIn).canExtractItem(index, stack, side);
}
public static ItemStack insertStack(IInventory inventoryIn, ItemStack stack, int index, Facing side)
{
ItemStack itemstack = inventoryIn.getStackInSlot(index);
if (canInsertItemInSlot(inventoryIn, stack, index, side))
{
boolean flag = false;
if (itemstack == null)
{
inventoryIn.setInventorySlotContents(index, stack);
stack = null;
flag = true;
}
else if (canCombine(itemstack, stack))
{
int i = stack.getMaxStackSize() - itemstack.getSize();
int j = Math.min(stack.getSize(), i);
stack.decrSize(j);
itemstack.incrSize(j);
flag = j > 0;
}
if (flag)
{
if (inventoryIn instanceof TileEntityPipe)
{
TileEntityPipe pipe = (TileEntityPipe)inventoryIn;
if (pipe.mayTransfer())
{
pipe.setTransferCooldown(Vars.pipeDelay);
}
inventoryIn.markDirty();
}
inventoryIn.markDirty();
}
}
return stack;
}
private IInventory getInventoryForTransfer()
{
State state = this.getState();
Facing enumfacing = state.getBlock() instanceof BlockPipe ? state.getValue(BlockPipe.FACING) : Facing.DOWN;
return getInventoryAtPosition(this.getWorld(), (double)(this.pos.getX() + enumfacing.getFrontOffsetX()), (double)(this.pos.getY() + enumfacing.getFrontOffsetY()), (double)(this.pos.getZ() + enumfacing.getFrontOffsetZ()));
}
public static IInventory getPipeInventory(TileEntityPipe pipe, boolean down)
{
return getInventoryAtPosition(pipe.getWorld(), pipe.getXPos(), pipe.getYPos() + (down ? -1.0 : 1.0), pipe.getZPos());
}
public static List<EntityItem> findDroppedItems(World world, double x, double y, double z)
{
return world.<EntityItem>getEntitiesWithinAABB(EntityItem.class, new BoundingBox(x - 0.5D, y - 0.5D, z - 0.5D, x + 0.5D, y + 0.5D, z + 0.5D), new Predicate<EntityItem>() {
public boolean test(EntityItem entity) {
return entity.isEntityAlive();
}
});
}
public static IInventory getInventoryAtPosition(World worldIn, double x, double y, double z)
{
IInventory iinventory = null;
int i = ExtMath.floord(x);
int j = ExtMath.floord(y);
int k = ExtMath.floord(z);
BlockPos blockpos = new BlockPos(i, j, k);
Block block = worldIn.getState(blockpos).getBlock();
if (block instanceof ITileEntityProvider)
{
TileEntity tileentity = worldIn.getTileEntity(blockpos);
if (tileentity instanceof IInventory)
{
iinventory = (IInventory)tileentity;
if (iinventory instanceof TileEntityChest && block instanceof BlockChest)
{
iinventory = ((BlockChest)block).getChest(worldIn, blockpos);
}
}
}
if (iinventory == null)
{
List<Entity> list = worldIn.getEntitiesInAABBexcluding((Entity)null, new BoundingBox(x - 0.5D, y - 0.5D, z - 0.5D, x + 0.5D, y + 0.5D, z + 0.5D), new Predicate<Entity>() {
public boolean test(Entity entity) {
return entity instanceof IInventory && entity.isEntityAlive();
}
});
if (list.size() > 0)
{
iinventory = (IInventory)list.get(worldIn.rand.zrange(list.size()));
}
}
return iinventory;
}
public static boolean canCombine(ItemStack stack1, ItemStack stack2)
{
return stack1.getItem() != stack2.getItem() ? false : (stack1.isOverLimit() ? false : ItemStack.dataEquals(stack1, stack2));
}
public void setTransferCooldown(int ticks)
{
this.cooldown = ticks;
}
public boolean isOnTransferCooldown()
{
return this.cooldown > 0;
}
public boolean mayTransfer()
{
return this.cooldown <= 1;
}
public int getColor() {
return 0x0040ff;
}
public class TileEntityPipe extends TileEntity implements IInventory, ITickable {
private ItemStack stack = null;
private int cooldown = -1;
public void readTags(TagObject tag) {
super.readTags(tag);
this.cooldown = tag.getInt("Cooldown");
this.stack = ItemStack.readFromTag(tag.getObject("Item"));
}
public void writeTags(TagObject tag) {
super.writeTags(tag);
tag.setInt("Cooldown", this.cooldown);
if(this.stack != null) {
TagObject item = new TagObject();
this.stack.writeTags(item);
tag.setObject("Item", item);
}
}
public int getSizeInventory() {
return 1;
}
public ItemStack getStackInSlot(int index) {
return this.stack;
}
public ItemStack decrStackSize(int index, int count) {
if(this.stack != null) {
if(this.stack.getSize() <= count) {
ItemStack itemstack1 = this.stack;
this.stack = null;
return itemstack1;
}
else {
ItemStack itemstack = this.stack.split(count);
if(this.stack.isEmpty()) {
this.stack = null;
}
return itemstack;
}
}
else {
return null;
}
}
public ItemStack removeStackFromSlot(int index) {
if(this.stack != null) {
ItemStack itemstack = this.stack;
this.stack = null;
return itemstack;
}
else {
return null;
}
}
public void setInventorySlotContents(int index, ItemStack stack) {
this.stack = stack;
}
public void clear() {
this.stack = null;
}
public boolean isUseableByPlayer(EntityNPC player) {
return this.world.getTileEntity(this.pos) != this ? false : player.getDistanceSq((double)this.pos.getX() + 0.5D, (double)this.pos.getY() + 0.5D, (double)this.pos.getZ() + 0.5D) <= 64.0D;
}
public void update() {
if(this.world != null && !this.world.client) {
--this.cooldown;
if(!this.isOnTransferCooldown()) {
this.setTransferCooldown(0);
this.updatePipe();
}
}
}
protected boolean updatePipe() {
if(!this.isOnTransferCooldown()) {
State state = this.getState();
if(!(state.getBlock() instanceof BlockPipe) /* || !this.decrPower() */) // TODO: power
return false;
boolean flag = false;
if(!this.isEmpty()) {
flag = this.transferOut();
}
if(!this.isFull()) {
flag |= this.transferIn(false);
}
if(flag) {
this.setTransferCooldown(Vars.pipeDelay);
this.markDirty();
return true;
}
}
return false;
}
private boolean isEmpty() {
return this.stack == null;
}
private boolean isFull() {
return this.stack != null && this.stack.isFull();
}
public void setTransferCooldown(int ticks) {
this.cooldown = ticks;
}
public boolean isOnTransferCooldown() {
return this.cooldown > 0;
}
public boolean mayTransfer() {
return this.cooldown <= 1;
}
public int getColor() {
return 0x0040ff;
}
// out
private static boolean isInventoryFull(IInventory inv, Facing side) {
if(inv instanceof ISidedInventory sided) {
int[] sides = sided.getSlotsForFace(side);
for(int k = 0; k < sides.length; ++k) {
ItemStack stack = sided.getStackInSlot(sides[k]);
if(stack == null || !stack.isFull()) {
return false;
}
}
}
else {
int i = inv.getSizeInventory();
for(int j = 0; j < i; ++j) {
ItemStack stack = inv.getStackInSlot(j);
if(stack == null || !stack.isFull()) {
return false;
}
}
}
return true;
}
protected boolean transferOut() {
State state = this.getState();
IInventory iinventory = this.getInventory(this.pos.offset(state.getValue(BlockPipe.FACING)), false);
if(iinventory == null)
return false;
Facing dir = state.getValue(BlockPipe.FACING).getOpposite();
if(isInventoryFull(iinventory, dir))
return false;
for(int i = 0; i < this.getSizeInventory(); ++i) {
if(this.getStackInSlot(i) != null) {
ItemStack itemstack = this.getStackInSlot(i).copy();
ItemStack itemstack1 = putStackInInventoryAllSlots(iinventory, this.decrStackSize(i, 1), dir);
if(itemstack1 == null || itemstack1.isEmpty()) {
iinventory.markDirty();
return true;
}
this.setInventorySlotContents(i, itemstack);
}
}
return false;
}
// in
private static boolean isInventoryEmpty(IInventory inv, Facing side) {
if(inv instanceof ISidedInventory sided) {
int[] slots = sided.getSlotsForFace(side);
for(int i = 0; i < slots.length; ++i) {
if(sided.getStackInSlot(slots[i]) != null) {
return false;
}
}
}
else {
int size = inv.getSizeInventory();
for(int k = 0; k < size; ++k) {
if(inv.getStackInSlot(k) != null) {
return false;
}
}
}
return true;
}
private static boolean putDropInInventoryAllSlots(IInventory p_145898_0_, EntityItem itemIn) {
boolean flag = false;
if(itemIn == null) {
return false;
}
else {
ItemStack itemstack = itemIn.getEntityItem().copy();
ItemStack itemstack1 = putStackInInventoryAllSlots(p_145898_0_, itemstack, (Facing)null);
if(itemstack1 != null && !itemstack1.isEmpty()) {
itemIn.setEntityItemStack(itemstack1);
}
else {
flag = true;
itemIn.setDead();
}
return flag;
}
}
private static boolean canExtractItemFromSlot(IInventory inventoryIn, ItemStack stack, int index, Facing side) {
return !(inventoryIn instanceof ISidedInventory) || ((ISidedInventory)inventoryIn).canExtractItem(index, stack, side);
}
private boolean pullItemFromSlot(IInventory inventoryIn, int index, Facing direction) {
ItemStack itemstack = inventoryIn.getStackInSlot(index);
if(itemstack != null && canExtractItemFromSlot(inventoryIn, itemstack, index, direction)) {
ItemStack itemstack1 = itemstack.copy();
ItemStack itemstack2 = putStackInInventoryAllSlots(this, inventoryIn.decrStackSize(index, 1), (Facing)null);
if(itemstack2 == null || itemstack2.isEmpty()) {
inventoryIn.markDirty();
return true;
}
inventoryIn.setInventorySlotContents(index, itemstack1);
}
return false;
}
private List<EntityItem> findDroppedItems(BlockPos pos) {
return this.world.<EntityItem>getEntitiesWithinAABB(EntityItem.class,
new BoundingBox((double)pos.getX(), (double)pos.getY(), (double)pos.getZ(), (double)pos.getX() + 1.0, (double)pos.getY() + 1.0, (double)pos.getZ() + 1.0), new Predicate<EntityItem>() {
public boolean test(EntityItem entity) {
return entity.isEntityAlive();
}
});
}
protected boolean transferIn(boolean suck) {
State state = this.getState();
Facing facing = state.getValue(BlockPipe.FACING);
for(Facing dir : Facing.values()) {
IInventory inv = dir == facing ? null : this.getInventory(this.pos.offset(dir), suck && dir == facing.getOpposite());
if(inv != null) {
Facing opposite = dir.getOpposite();
if(isInventoryEmpty(inv, opposite)) {
continue;
}
if(inv instanceof ISidedInventory sided) {
int[] slots = sided.getSlotsForFace(opposite);
for(int i = 0; i < slots.length; ++i) {
if(this.pullItemFromSlot(inv, slots[i], opposite)) {
return true;
}
}
}
else {
int size = inv.getSizeInventory();
for(int k = 0; k < size; ++k) {
if(this.pullItemFromSlot(inv, k, opposite)) {
return true;
}
}
}
}
else if(suck && dir == facing.getOpposite()) {
for(EntityItem entity : this.findDroppedItems(this.pos.offset(dir))) {
if(putDropInInventoryAllSlots(this, entity)) {
return true;
}
}
}
}
return false;
}
// common
private static boolean canInsertItemInSlot(IInventory inventoryIn, ItemStack stack, int index, Facing side) {
return !inventoryIn.isItemValidForSlot(index, stack) ? false : !(inventoryIn instanceof ISidedInventory) || ((ISidedInventory)inventoryIn).canInsertItem(index, stack, side);
}
private static boolean canCombine(ItemStack stack1, ItemStack stack2) {
return stack1.getItem() != stack2.getItem() ? false : (stack1.isOverLimit() ? false : ItemStack.dataEquals(stack1, stack2));
}
private static ItemStack insertStack(IInventory inventoryIn, ItemStack stack, int index, Facing side) {
ItemStack itemstack = inventoryIn.getStackInSlot(index);
if(canInsertItemInSlot(inventoryIn, stack, index, side)) {
boolean flag = false;
if(itemstack == null) {
inventoryIn.setInventorySlotContents(index, stack);
stack = null;
flag = true;
}
else if(canCombine(itemstack, stack)) {
int i = stack.getMaxStackSize() - itemstack.getSize();
int j = Math.min(stack.getSize(), i);
stack.decrSize(j);
itemstack.incrSize(j);
flag = j > 0;
}
if(flag) {
if(inventoryIn instanceof TileEntityPipe) {
TileEntityPipe pipe = (TileEntityPipe)inventoryIn;
if(pipe.mayTransfer()) {
pipe.setTransferCooldown(Vars.pipeDelay);
}
inventoryIn.markDirty();
}
inventoryIn.markDirty();
}
}
return stack;
}
private static ItemStack putStackInInventoryAllSlots(IInventory inventoryIn, ItemStack stack, Facing side) {
if(inventoryIn instanceof ISidedInventory && side != null) {
ISidedInventory isidedinventory = (ISidedInventory)inventoryIn;
int[] aint = isidedinventory.getSlotsForFace(side);
for(int k = 0; k < aint.length && stack != null && !stack.isEmpty(); ++k) {
stack = insertStack(inventoryIn, stack, aint[k], side);
}
}
else {
int i = inventoryIn.getSizeInventory();
for(int j = 0; j < i && stack != null && !stack.isEmpty(); ++j) {
stack = insertStack(inventoryIn, stack, j, side);
}
}
if(stack != null && stack.isEmpty()) {
stack = null;
}
return stack;
}
private IInventory getEntityInventory(BlockPos pos) {
List<Entity> list = this.world.getEntitiesInAABBexcluding((Entity)null,
new BoundingBox(this.getXPos() - 0.5D, this.getYPos() - 0.5D, this.getZPos() - 0.5D, this.getXPos() + 0.5D, this.getYPos() + 0.5D, this.getZPos() + 0.5D), new Predicate<Entity>() {
public boolean test(Entity entity) {
return entity instanceof IInventory && !(entity instanceof EntityLiving) && entity.isEntityAlive();
}
});
return list.size() > 0 ? (IInventory)list.get(this.world.rand.zrange(list.size())) : null;
}
private IInventory getInventory(BlockPos blockpos, boolean suck) {
IInventory inv = null;
Block block = this.world.getState(blockpos).getBlock();
if(block instanceof ITileEntityProvider) {
TileEntity te = this.world.getTileEntity(blockpos);
if(te instanceof IInventory) {
inv = (IInventory)te;
if(inv instanceof TileEntityChest && block instanceof BlockChest) {
inv = ((BlockChest)block).getChest(this.world, blockpos);
}
}
}
return inv == null && suck ? this.getEntityInventory(blockpos) : inv;
}
}