PrettyPipes/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java

169 lines
6.2 KiB
Java
Raw Normal View History

2020-04-16 04:42:42 +02:00
package de.ellpeck.prettypipes.pipe;
2020-04-14 01:38:48 +02:00
import de.ellpeck.prettypipes.PrettyPipes;
import de.ellpeck.prettypipes.Registry;
2020-04-16 00:39:53 +02:00
import de.ellpeck.prettypipes.items.IModule;
2020-04-14 17:14:24 +02:00
import de.ellpeck.prettypipes.network.PipeItem;
2020-04-16 23:40:35 +02:00
import de.ellpeck.prettypipes.pipe.modules.containers.MainPipeContainer;
2020-04-14 01:38:48 +02:00
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.INamedContainerProvider;
2020-04-16 00:39:53 +02:00
import net.minecraft.item.Item;
2020-04-14 01:38:48 +02:00
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
2020-04-14 17:14:24 +02:00
import net.minecraft.nbt.ListNBT;
2020-04-16 00:39:53 +02:00
import net.minecraft.profiler.IProfiler;
2020-04-14 17:14:24 +02:00
import net.minecraft.tileentity.ITickableTileEntity;
2020-04-14 01:38:48 +02:00
import net.minecraft.tileentity.TileEntity;
2020-04-14 17:14:24 +02:00
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
2020-04-14 01:38:48 +02:00
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
2020-04-14 17:14:24 +02:00
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
2020-04-14 01:38:48 +02:00
import net.minecraftforge.items.ItemStackHandler;
2020-04-16 04:42:42 +02:00
import org.apache.commons.lang3.tuple.Pair;
2020-04-14 01:38:48 +02:00
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
2020-04-16 04:42:42 +02:00
import java.util.*;
2020-04-16 00:39:53 +02:00
import java.util.stream.Stream;
2020-04-14 01:38:48 +02:00
2020-04-16 04:42:42 +02:00
public class PipeTileEntity extends TileEntity implements INamedContainerProvider, ITickableTileEntity {
2020-04-14 01:38:48 +02:00
2020-04-16 00:39:53 +02:00
public final ItemStackHandler modules = new ItemStackHandler(3) {
2020-04-14 01:38:48 +02:00
@Override
public boolean isItemValid(int slot, @Nonnull ItemStack stack) {
Item item = stack.getItem();
if (!(item instanceof IModule))
return false;
IModule module = (IModule) item;
2020-04-16 04:42:42 +02:00
return PipeTileEntity.this.streamModules().allMatch(m -> module.isCompatible(stack, PipeTileEntity.this, m.getRight()) && m.getRight().isCompatible(m.getLeft(), PipeTileEntity.this, module));
}
@Override
public int getSlotLimit(int slot) {
return 1;
2020-04-14 01:38:48 +02:00
}
};
2020-04-14 17:14:24 +02:00
public final List<PipeItem> items = new ArrayList<>();
2020-04-14 01:38:48 +02:00
public PipeTileEntity() {
super(Registry.pipeTileEntity);
}
@Override
public CompoundNBT write(CompoundNBT compound) {
2020-04-16 00:39:53 +02:00
compound.put("modules", this.modules.serializeNBT());
2020-04-14 17:14:24 +02:00
ListNBT list = new ListNBT();
for (PipeItem item : this.items)
list.add(item.serializeNBT());
compound.put("items", list);
2020-04-14 01:38:48 +02:00
return super.write(compound);
}
@Override
public void read(CompoundNBT compound) {
2020-04-16 00:39:53 +02:00
this.modules.deserializeNBT(compound.getCompound("modules"));
2020-04-14 17:14:24 +02:00
this.items.clear();
ListNBT list = compound.getList("items", Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < list.size(); i++)
this.items.add(new PipeItem(list.getCompound(i)));
2020-04-14 01:38:48 +02:00
super.read(compound);
}
2020-04-14 17:14:24 +02:00
2020-04-14 21:04:41 +02:00
@Override
public CompoundNBT getUpdateTag() {
// by default, this is just writeInternal, but we
// want to sync the current pipe items on load too
return this.write(new CompoundNBT());
}
2020-04-14 17:14:24 +02:00
@Override
public void tick() {
2020-04-14 21:04:41 +02:00
if (!this.world.isAreaLoaded(this.pos, 1))
return;
2020-04-16 00:39:53 +02:00
IProfiler profiler = this.world.getProfiler();
2020-04-14 21:04:41 +02:00
2020-04-16 00:39:53 +02:00
profiler.startSection("ticking_modules");
2020-04-16 04:42:42 +02:00
this.streamModules().forEach(m -> m.getRight().tick(m.getLeft(), this));
2020-04-16 00:39:53 +02:00
profiler.endSection();
profiler.startSection("ticking_items");
2020-04-14 17:14:24 +02:00
for (int i = this.items.size() - 1; i >= 0; i--)
this.items.get(i).updateInPipe(this);
2020-04-16 00:39:53 +02:00
profiler.endSection();
}
2020-04-14 17:14:24 +02:00
2020-04-16 00:39:53 +02:00
public boolean isConnected(Direction dir) {
return this.getBlockState().get(PipeBlock.DIRECTIONS.get(dir)).isConnected();
2020-04-14 17:14:24 +02:00
}
public BlockPos getAvailableDestination(ItemStack stack) {
2020-04-16 04:42:42 +02:00
if (this.streamModules().anyMatch(m -> !m.getRight().canAcceptItem(m.getLeft(), this, stack)))
2020-04-16 00:39:53 +02:00
return null;
2020-04-14 17:14:24 +02:00
for (Direction dir : Direction.values()) {
IItemHandler handler = this.getItemHandler(dir);
if (handler == null)
continue;
2020-04-16 00:39:53 +02:00
if (!ItemHandlerHelper.insertItem(handler, stack, true).isEmpty())
continue;
2020-04-16 04:42:42 +02:00
if (this.streamModules().anyMatch(m -> !m.getRight().isAvailableDestination(m.getLeft(), this, stack, handler)))
2020-04-16 00:39:53 +02:00
continue;
return this.pos.offset(dir);
2020-04-14 17:14:24 +02:00
}
return null;
}
2020-04-15 02:16:23 +02:00
public int getPriority() {
2020-04-16 04:42:42 +02:00
return this.streamModules().mapToInt(m -> m.getRight().getPriority(m.getLeft(), this)).max().orElse(0);
2020-04-15 02:16:23 +02:00
}
2020-04-16 23:40:35 +02:00
public float getItemSpeed() {
float speed = (float) this.streamModules().mapToDouble(m -> m.getRight().getItemSpeedIncrease(m.getLeft(), this)).sum();
return 0.05F + speed;
}
2020-04-16 00:39:53 +02:00
public IItemHandler getItemHandler(Direction dir) {
if (!this.isConnected(dir))
2020-04-14 17:14:24 +02:00
return null;
TileEntity tile = this.world.getTileEntity(this.pos.offset(dir));
if (tile == null)
return null;
2020-04-14 18:51:43 +02:00
return tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, dir.getOpposite()).orElse(null);
2020-04-14 17:14:24 +02:00
}
2020-04-15 18:35:00 +02:00
public boolean isConnectedInventory(Direction dir) {
return this.getItemHandler(dir) != null;
}
public boolean isConnectedInventory() {
return Arrays.stream(Direction.values()).anyMatch(this::isConnectedInventory);
}
2020-04-16 00:39:53 +02:00
2020-04-16 23:40:35 +02:00
private Stream<Pair<ItemStack, IModule>> streamModules() {
2020-04-16 04:42:42 +02:00
Stream.Builder<Pair<ItemStack, IModule>> builder = Stream.builder();
2020-04-16 00:39:53 +02:00
for (int i = 0; i < this.modules.getSlots(); i++) {
ItemStack stack = this.modules.getStackInSlot(i);
if (stack.isEmpty())
continue;
2020-04-16 04:42:42 +02:00
builder.accept(Pair.of(stack, (IModule) stack.getItem()));
2020-04-16 00:39:53 +02:00
}
return builder.build();
}
2020-04-16 04:42:42 +02:00
@Override
public ITextComponent getDisplayName() {
return new TranslationTextComponent("container." + PrettyPipes.ID + ".pipe");
}
@Nullable
@Override
public Container createMenu(int window, PlayerInventory inv, PlayerEntity player) {
return new MainPipeContainer(Registry.pipeContainer, window, player, PipeTileEntity.this.pos);
}
2020-04-14 01:38:48 +02:00
}