2020-04-14 01:38:48 +02:00
|
|
|
package de.ellpeck.prettypipes.blocks.pipe;
|
|
|
|
|
|
|
|
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-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;
|
|
|
|
|
|
|
|
import javax.annotation.Nonnull;
|
|
|
|
import javax.annotation.Nullable;
|
2020-04-14 17:14:24 +02:00
|
|
|
import java.util.ArrayList;
|
2020-04-15 18:35:00 +02:00
|
|
|
import java.util.Arrays;
|
2020-04-14 17:14:24 +02:00
|
|
|
import java.util.List;
|
2020-04-16 00:39:53 +02:00
|
|
|
import java.util.stream.Stream;
|
2020-04-14 01:38:48 +02:00
|
|
|
|
2020-04-16 02:48:58 +02:00
|
|
|
public class PipeTileEntity extends TileEntity implements 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) {
|
2020-04-16 02:48:58 +02:00
|
|
|
Item item = stack.getItem();
|
|
|
|
if (!(item instanceof IModule))
|
|
|
|
return false;
|
|
|
|
IModule module = (IModule) item;
|
|
|
|
return PipeTileEntity.this.streamModules().allMatch(m -> module.isCompatible(PipeTileEntity.this, m) && m.isCompatible(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");
|
|
|
|
this.streamModules().forEach(m -> m.tick(this));
|
|
|
|
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 00:39:53 +02:00
|
|
|
if (this.streamModules().anyMatch(u -> !u.canAcceptItem(this, stack)))
|
|
|
|
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;
|
|
|
|
if (this.streamModules().anyMatch(u -> !u.isAvailableDestination(this, stack, handler)))
|
|
|
|
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 00:39:53 +02:00
|
|
|
return this.streamModules().mapToInt(u -> u.getPriority(this)).max().orElse(0);
|
2020-04-15 02:16:23 +02:00
|
|
|
}
|
|
|
|
|
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 02:48:58 +02:00
|
|
|
public Stream<IModule> streamModules() {
|
2020-04-16 00:39:53 +02:00
|
|
|
Stream.Builder<IModule> builder = Stream.builder();
|
|
|
|
for (int i = 0; i < this.modules.getSlots(); i++) {
|
|
|
|
ItemStack stack = this.modules.getStackInSlot(i);
|
|
|
|
if (stack.isEmpty())
|
|
|
|
continue;
|
2020-04-16 02:48:58 +02:00
|
|
|
builder.accept((IModule) stack.getItem());
|
2020-04-16 00:39:53 +02:00
|
|
|
}
|
|
|
|
return builder.build();
|
|
|
|
}
|
2020-04-16 02:48:58 +02:00
|
|
|
|
|
|
|
public INamedContainerProvider createContainer(int openModule) {
|
|
|
|
ItemStack moduleStack = openModule < 0 ? null : this.modules.getStackInSlot(openModule);
|
|
|
|
return new INamedContainerProvider() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public ITextComponent getDisplayName() {
|
|
|
|
if (moduleStack != null)
|
|
|
|
return moduleStack.getDisplayName();
|
|
|
|
return new TranslationTextComponent("container." + PrettyPipes.ID + ".pipe");
|
|
|
|
}
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
@Override
|
|
|
|
public Container createMenu(int window, PlayerInventory inv, PlayerEntity player) {
|
|
|
|
IModule module = moduleStack == null ? null : (IModule) moduleStack.getItem();
|
|
|
|
return new PipeContainer(Registry.pipeContainer, window, player, PipeTileEntity.this, module);
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
}
|
2020-04-14 01:38:48 +02:00
|
|
|
}
|