I don't want to upload all my code online yet, sorry. But I can post the main classes of just the block here and maybe you all can check if I'm missing something?
Block Class:
public class DEBlock_TinkeringTable extends Block implements DEMachineNetworkHandler.IDENetworkBlock{
public DEBlock_TinkeringTable() {
super(Properties.create(Material.ROCK).hardnessAndResistance(2.0f).sound(SoundType.METAL));
this.setDefaultState(stateContainer.getBaseState().with(BlockStateProperties.HORIZONTAL_FACING, Direction.NORTH));
}
@SuppressWarnings("deprecation")
@Override
public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult trace) {
if (!world.isRemote) {
TileEntity tileEntity = world.getTileEntity(pos);
if (tileEntity instanceof DETileEntity_TinkeringTable) {
INamedContainerProvider containerProvider = new INamedContainerProvider() {
@Override
public ITextComponent getDisplayName() {
return new TranslationTextComponent("block.demonenergistics.tinkeringtable");
}
@Override
public Container createMenu(int id, PlayerInventory playerInventory, PlayerEntity playerEntity) {
return new DEContainer_TinkeringTable(id, world, pos, playerInventory, playerEntity);
}
};
NetworkHooks.openGui((ServerPlayerEntity) player, containerProvider, tileEntity.getPos());
}
}
return ActionResultType.SUCCESS;
}
@Nullable
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
return getDefaultState().with(BlockStateProperties.HORIZONTAL_FACING, context.getPlacementHorizontalFacing().getOpposite());
}
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) {
builder.add(BlockStateProperties.HORIZONTAL_FACING);
}
@Override
public boolean hasTileEntity(BlockState state) {
return true;
}
@Nullable
@Override
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
return new DETileEntity_TinkeringTable();
}
}
TileEntity Class:
public class DETileEntity_TinkeringTable extends TileEntity implements ITickableTileEntity, DEMachineNetworkHandler.IDESapReciever {
private final int CELL_SLOT = 9;
private final int OUTPUT_SLOT = 10;
private int ticksleft = 0;
private int currentcrafttime = 0;
private int requiresfluid = 0;
public final IIntArray tiledata = new IIntArray() {
@Override
public int size() {
return 3;
}
@Override
public void set(int index, int value) {
switch (index) {
case 0:
DETileEntity_TinkeringTable.this.ticksleft = value;
break;
case 1:
DETileEntity_TinkeringTable.this.currentcrafttime = value;
break;
case 2:
DETileEntity_TinkeringTable.this.requiresfluid = value;
}
}
@Override
public int get(int index) {
switch (index) {
case 0:
return DETileEntity_TinkeringTable.this.ticksleft;
case 1:
return DETileEntity_TinkeringTable.this.currentcrafttime;
case 2:
return DETileEntity_TinkeringTable.this.requiresfluid;
}
return index;
}
};
private ItemStackHandler itemhandler = new ItemStackHandler(11) {
@Override
protected void onContentsChanged(int slot) {
markDirty();
}
@Override
public boolean isItemValid(int slot, @Nonnull ItemStack stack) {
if (slot == CELL_SLOT && stack.getItem() instanceof DEItem_DemonCell) {
return true;
} else {
return slot < CELL_SLOT;
}
}
};
private LazyOptional<IItemHandler> items = LazyOptional.of(() -> itemhandler);
public DETileEntity_TinkeringTable() {
super(DEBlocks.TINKERINGTABLE_TILEENTITY.get());
}
@Override
public void tick() {
if (!world.isRemote && itemhandler.getStackInSlot(OUTPUT_SLOT).isEmpty()) {
RecipeTinkeringTable tocraft = null;
for (final IRecipe<?> recipe : DERecipes.getRecipes(DERecipes.TINKERINGTABLE, world.getRecipeManager()).values()) {
if (recipe instanceof RecipeTinkeringTable) {
final RecipeTinkeringTable tinkeringtablerecipe = (RecipeTinkeringTable) recipe;
if (tinkeringtablerecipe.isValid(itemhandler)) {
tocraft = tinkeringtablerecipe;
break;
}
}
}
if (tocraft != null) {
if (tocraft.getRequiredFluid() > this.getHeldFluid()) {
requiresfluid = 1;
stopIfCrafting();
} else {
requiresfluid = 0;
if (isCrafting()) {
ticksleft--;
if (ticksleft == 0) {
doCraft(tocraft);
currentcrafttime = 0;
}
} else {
startCraft(tocraft);
}
}
} else {
requiresfluid = 0;
stopIfCrafting();
}
}
}
private void stopIfCrafting() {
if (isCrafting()) {
ticksleft = 0;
currentcrafttime = 0;
requiresfluid = 0;
this.markDirty();
}
}
private boolean isCrafting() {
return ticksleft > 0;
}
private void startCraft(RecipeTinkeringTable recipe) {
currentcrafttime = recipe.getCraftTime();
ticksleft = recipe.getCraftTime();
}
private void doCraft(RecipeTinkeringTable recipe) {
if (recipe.getRequiredFluid() == 0) {
itemhandler.setStackInSlot(OUTPUT_SLOT, recipe.getRecipeOutput().copy());
for (int i = 0; i < RecipeTinkeringTable.INPUT_SIZE; i++) {
itemhandler.extractItem(i, 1, false);
}
} else {
ItemStack cell = itemhandler.getStackInSlot(CELL_SLOT);
if (!cell.isEmpty()) {
IFluidHandlerItem flhd = FluidUtil.getFluidHandler(cell).orElse(null);
if (flhd != null) {
Optional<FluidStack> containedFluid = FluidUtil.getFluidContained(cell);
if (containedFluid.isPresent()) {
if (containedFluid.get().getAmount() >= recipe.getRequiredFluid()) {
flhd.drain(new FluidStack(DEFluids.DEMONSAP.get(), recipe.getRequiredFluid()), IFluidHandler.FluidAction.EXECUTE);
for (int i = 0; i < RecipeTinkeringTable.INPUT_SIZE; i++) {
itemhandler.extractItem(i, 1, false);
}
itemhandler.setStackInSlot(OUTPUT_SLOT, recipe.getRecipeOutput().copy());
this.stopIfCrafting();
}
}
}
}
}
}
private int getHeldFluid() {
ItemStack cell = itemhandler.getStackInSlot(CELL_SLOT);
if (!cell.isEmpty()) {
IFluidHandlerItem flhd = FluidUtil.getFluidHandler(cell).orElse(null);
if (flhd != null) {
Optional<FluidStack> containedFluid = FluidUtil.getFluidContained(cell);
if (containedFluid.isPresent()) {
return containedFluid.get().getAmount();
}
}
}
return 0;
}
@Override
public void remove() {
super.remove();
items.invalidate();
}
@Override
public void read(BlockState state, CompoundNBT tag) {
itemhandler.deserializeNBT(tag.getCompound("inventory"));
ticksleft = tag.getInt("ticksleft");
currentcrafttime = tag.getInt("currentcrafttime");
requiresfluid = tag.getInt("requiresfluid");
super.read(state, tag);
}
@Override
public CompoundNBT write(CompoundNBT tag) {
tag.put("inventory", itemhandler.serializeNBT());
tag.putInt("ticksleft", ticksleft);
tag.putInt("currentcrafttime", currentcrafttime);
tag.putInt("requiresfluid", requiresfluid);
return super.write(tag);
}
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
return items.cast();
}
return super.getCapability(cap, side);
}
@Override
public List<Integer> getCellSlots() {
return Arrays.asList(CELL_SLOT);
}
@Override
public ItemStackHandler getInventory() {
return itemhandler;
}
}
Container Class:
public class DEContainer_TinkeringTable extends Container {
private TileEntity tileentity;
private PlayerEntity player;
private IItemHandler playerinv;
private IIntArray tiledata;
public DEContainer_TinkeringTable(int id, World world, BlockPos pos, PlayerInventory playerInventory, PlayerEntity playerin) {
super(DEBlocks.TINKERINGTABLE_CONTAINER.get(), id);
playerinv = new InvWrapper(playerInventory);
tileentity = world.getTileEntity(pos);
player = playerin;
if (tileentity != null) {
tileentity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).ifPresent(handler -> {
int index = 0;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
addSlot(new SlotItemHandler(handler, index++, 30 + j * 18, 17 + i * 18));
}
}
addSlot(new SlotItemHandler(handler, index++, 98, 53));
addSlot(new SlotItemHandler(handler, index, 132, 26) {
@Override
public boolean isItemValid(ItemStack stack) {
return false;
}
});
});
tiledata = ((DETileEntity_TinkeringTable) tileentity).tiledata;
}
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 9; ++j) {
addSlot(new SlotItemHandler(playerinv, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
}
}
for (int k = 0; k < 9; ++k) {
addSlot(new SlotItemHandler(playerinv, k, 8 + k * 18, 142));
}
trackIntArray(tiledata);
}
@OnlyIn(Dist.CLIENT)
public float getCraftProgress() {
return 1 - (float) tiledata.get(0) / tiledata.get(1);
}
@OnlyIn(Dist.CLIENT)
public boolean getRequiresFluid() {
return tiledata.get(2) == 1;
}
@Override
public boolean canInteractWith(PlayerEntity playerIn) {
return isWithinUsableDistance(IWorldPosCallable.of(tileentity.getWorld(), tileentity.getPos()), playerIn, DEBlocks.TINKERINGTABLE.get());
}
@Override
public ItemStack transferStackInSlot(PlayerEntity playerIn, int slotid) {
ItemStack newitem = ItemStack.EMPTY;
Slot slot = this.inventorySlots.get(slotid);
if (slot != null && slot.getHasStack()) {
ItemStack iteminslot = slot.getStack();
newitem = iteminslot.copy();
if (slotid < 11) {
if (!this.mergeItemStack(iteminslot, 11, this.inventorySlots.size(), true)) {
return ItemStack.EMPTY;
}
} else if (iteminslot.getItem() instanceof DEItem_DemonCell) {
if (!this.mergeItemStack(iteminslot, 9, 10, false)) {
return ItemStack.EMPTY;
}
} else if (!this.mergeItemStack(iteminslot, 0, 11, false)) {
return ItemStack.EMPTY;
}
if (iteminslot.isEmpty()) {
slot.putStack(ItemStack.EMPTY);
} else {
slot.onSlotChanged();
}
}
return newitem;
}
}
Screen Class:
public class DEScreen_TinkeringTable extends ContainerScreen<DEContainer_TinkeringTable> {
public static final ResourceLocation GUI = new ResourceLocation(DEMod.MODID, "textures/gui/tinkeringtable.png");
public DEScreen_TinkeringTable(DEContainer_TinkeringTable screenContainer, PlayerInventory inv, ITextComponent titleIn) {
super(screenContainer, inv, titleIn);
}
@Override
public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
this.renderBackground(matrixStack);
super.render(matrixStack, mouseX, mouseY, partialTicks);
this.renderHoveredTooltip(matrixStack, mouseX, mouseY);
}
@Override
protected void drawGuiContainerForegroundLayer(MatrixStack matrixStack, int mouseX, int mouseY) {
int relX = (this.width - this.xSize) / 2;
int relY = (this.height - this.ySize) / 2;
if (mouseX >= relX + 99 && mouseY >= relY + 10 && mouseX <= relX + 114 && mouseY <= relY + 25) {
if (container.getRequiresFluid()) {
renderTooltip(matrixStack, new TranslationTextComponent("container.demonenergistics.requiresfluid"), mouseX - relX, mouseY - relY);
}
}
}
@Override
protected void drawGuiContainerBackgroundLayer(MatrixStack matrixStack, float partialTicks, int mouseX, int mouseY) {
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
this.minecraft.getTextureManager().bindTexture(GUI);
int relX = (this.width - this.xSize) / 2;
int relY = (this.height - this.ySize) / 2;
this.blit(matrixStack, relX, relY, 0, 0, this.xSize, this.ySize);
this.blit(matrixStack, relX + 95, relY + 26, 176, 23, (int) (container.getCraftProgress() * 24), 16);
if (container.getRequiresFluid()) {
this.blit(matrixStack, relX + 96, relY + 7, 198, 0, 21, 22);
} else if (container.getCraftProgress() > 0) {
this.blit(matrixStack, relX + 96, relY + 7, 176, 0, 21, 22);
}
}
}