Jump to content

[1.15.2] [SOLVED] Can not open Tile Entity Screen


Skyriis

Recommended Posts

Hey Guys,

 

i've created my first tile entity but the screen won't open if i r-click on my block.

 

I'm getting the following warning:

[14:28:03] [Render thread/WARN] [minecraft/ScreenManager]: Failed to create screen for menu type: blutmondrpg:alloy_furnace_container

 

ScreenManager Registration:

private void clientSetup(final FMLClientSetupEvent e) {
        ScreenManager.registerFactory(ContainerList.ALLOY_FURNACE.get(), AlloyFurnaceScreen::new);
    }

 

Container:

Spoiler

package de.blutmondgilde.blutmondrpg.tileentities.alloyfurnace;

import de.blutmondgilde.blutmondrpg.tileentities.ContainerList;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;


public class AlloyFurnaceContainer extends Container {
    public static AlloyFurnaceContainer createContainerServerSide(int windowID, PlayerInventory playerInventory, AlloyFurnaceZoneContents inputZoneContents, AlloyFurnaceZoneContents outputZoneContents, AlloyFurnaceZoneContents fuelZoneContents, AlloyFurnaceStateData furnaceStateData) {
        return new AlloyFurnaceContainer(windowID, playerInventory, inputZoneContents, outputZoneContents, fuelZoneContents, furnaceStateData);
    }

    public static AlloyFurnaceContainer createContainerClientSide(int windowID, PlayerInventory playerInventory, PacketBuffer extraData) {
        AlloyFurnaceZoneContents inputZoneContents = AlloyFurnaceZoneContents.createForClientSideContainer(INPUT_SLOTS_COUNT);
        AlloyFurnaceZoneContents outputZoneContents = AlloyFurnaceZoneContents.createForClientSideContainer(OUTPUT_SLOTS_COUNT);
        AlloyFurnaceZoneContents fuelZoneContents = AlloyFurnaceZoneContents.createForClientSideContainer(FUEL_SLOTS_COUNT);
        AlloyFurnaceStateData furnaceStateData = new AlloyFurnaceStateData();

        return new AlloyFurnaceContainer(windowID, playerInventory, inputZoneContents, outputZoneContents, fuelZoneContents, furnaceStateData);
    }

    private static final int HOTBAR_SLOT_COUNT = 9;
    private static final int PLAYER_INVENTORY_ROW_COUNT = 3;
    private static final int PLAYER_INVENTORY_COLUMN_COUNT = 9;
    private static final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT;
    private static final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT;

    public static final int FUEL_SLOTS_COUNT = AlloyFurnaceTileEntity.FUEL_SLOTS_COUNT;
    public static final int INPUT_SLOTS_COUNT = AlloyFurnaceTileEntity.INPUT_SLOTS_COUNT;
    public static final int OUTPUT_SLOTS_COUNT = AlloyFurnaceTileEntity.OUTPUT_SLOTS_COUNT;
    public static final int FURNACE_SLOTS_COUNT = FUEL_SLOTS_COUNT + INPUT_SLOTS_COUNT + OUTPUT_SLOTS_COUNT;

    private static final int VANILLA_FIRST_SLOT_INDEX = 0;
    private static final int HOTBAR_FIRST_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX;
    private static final int PLAYER_INVENTORY_FIRST_SLOT_INDEX = HOTBAR_FIRST_SLOT_INDEX + HOTBAR_SLOT_COUNT;
    private static final int FIRST_FUEL_SLOT_INDEX = PLAYER_INVENTORY_FIRST_SLOT_INDEX + PLAYER_INVENTORY_SLOT_COUNT;
    private static final int FIRST_INPUT_SLOT_INDEX = FIRST_FUEL_SLOT_INDEX + FUEL_SLOTS_COUNT;
    private static final int FIRST_OUTPUT_SLOT_INDEX = FIRST_INPUT_SLOT_INDEX + INPUT_SLOTS_COUNT;

    public AlloyFurnaceContainer(int windowID, PlayerInventory invPlayer, AlloyFurnaceZoneContents inputZoneContents, AlloyFurnaceZoneContents outputZoneContents, AlloyFurnaceZoneContents fuelZoneContents, AlloyFurnaceStateData furnaceStateData) {
        super(ContainerList.ALLOY_FURNACE.get(), windowID);
        this.inputZoneContents = inputZoneContents;
        this.outputZoneContents = outputZoneContents;
        this.fuelZoneContents = fuelZoneContents;
        this.furnaceStateData = furnaceStateData;
        this.world = invPlayer.player.world;

        trackIntArray(furnaceStateData);

        final int SLOT_X_SPACING = 18;
        final int SLOT_Y_SPACING = 18;
        final int HOTBAR_XPOS = 8;
        final int HOTBAR_YPOS = 183;

        for (int x = 0; x < HOTBAR_SLOT_COUNT; x++) {
            int slotNumber = x;
            addSlot(new Slot(invPlayer, slotNumber, HOTBAR_XPOS + SLOT_X_SPACING * x, HOTBAR_YPOS));
        }

        final int PLAYER_INVENTORY_XPOS = 8;
        final int PLAYER_INVENTORY_YPOS = 125;

        for (int y = 0; y < PLAYER_INVENTORY_ROW_COUNT; y++) {
            for (int x = 0; x < PLAYER_INVENTORY_COLUMN_COUNT; x++) {
                int slotNumber = HOTBAR_SLOT_COUNT + y * PLAYER_INVENTORY_COLUMN_COUNT + x;
                int xpos = PLAYER_INVENTORY_XPOS + x * SLOT_X_SPACING;
                int ypos = PLAYER_INVENTORY_YPOS + y * SLOT_Y_SPACING;
                addSlot(new Slot(invPlayer, slotNumber, xpos, ypos));
            }
        }

        final int FUEL_SLOTS_XPOS = 53;
        final int FUEL_SLOTS_YPOS = 96;
        // Add the tile fuel slots
        for (int x = 0; x < FUEL_SLOTS_COUNT; x++) {
            int slotNumber = x;
            addSlot(new SlotFuel(fuelZoneContents, slotNumber, FUEL_SLOTS_XPOS + SLOT_X_SPACING * x, FUEL_SLOTS_YPOS));
        }

        final int INPUT_SLOTS_XPOS = 26;
        final int INPUT_SLOTS_YPOS = 24;
        // Add the tile input slots
        for (int y = 0; y < INPUT_SLOTS_COUNT; y++) {
            int slotNumber = y;
            addSlot(new SlotSmeltableInput(inputZoneContents, slotNumber, INPUT_SLOTS_XPOS, INPUT_SLOTS_YPOS + SLOT_Y_SPACING * y));
        }

        final int OUTPUT_SLOTS_XPOS = 134;
        final int OUTPUT_SLOTS_YPOS = 24;
        for (int y = 0; y < OUTPUT_SLOTS_COUNT; y++) {
            int slotNumber = y;
            addSlot(new SlotOutput(outputZoneContents, slotNumber, OUTPUT_SLOTS_XPOS, OUTPUT_SLOTS_YPOS + SLOT_Y_SPACING * y));
        }
    }

    @Override
    public boolean canInteractWith(PlayerEntity player) {
        return fuelZoneContents.isUsableByPlayer(player) && inputZoneContents.isUsableByPlayer(player)
                && outputZoneContents.isUsableByPlayer(player);
    }

    @Override
    public ItemStack transferStackInSlot(PlayerEntity player, int sourceSlotIndex) {
        Slot sourceSlot = inventorySlots.get(sourceSlotIndex);
        if (sourceSlot == null || !sourceSlot.getHasStack()) return ItemStack.EMPTY;
        ItemStack sourceItemStack = sourceSlot.getStack();
        ItemStack sourceStackBeforeMerge = sourceItemStack.copy();
        boolean successfulTransfer = false;

        SlotZone sourceZone = SlotZone.getZoneFromIndex(sourceSlotIndex);

        switch (sourceZone) {
            case OUTPUT_ZONE:
                successfulTransfer = mergeInto(SlotZone.PLAYER_HOTBAR, sourceItemStack, true);
                if (!successfulTransfer) {
                    successfulTransfer = mergeInto(SlotZone.PLAYER_MAIN_INVENTORY, sourceItemStack, true);
                }
                if (successfulTransfer) {
                    sourceSlot.onSlotChange(sourceItemStack, sourceStackBeforeMerge);
                }
                break;

            case INPUT_ZONE:
            case FUEL_ZONE:
                successfulTransfer = mergeInto(SlotZone.PLAYER_MAIN_INVENTORY, sourceItemStack, false);
                if (!successfulTransfer) {
                    successfulTransfer = mergeInto(SlotZone.PLAYER_HOTBAR, sourceItemStack, false);
                }
                break;

            case PLAYER_HOTBAR:
            case PLAYER_MAIN_INVENTORY:
                if (!AlloyFurnaceTileEntity.getSmeltingResultForItem(world, sourceItemStack).isEmpty()) {
                    successfulTransfer = mergeInto(SlotZone.INPUT_ZONE, sourceItemStack, false);
                }
                if (!successfulTransfer && AlloyFurnaceTileEntity.getItemBurnTime(world, sourceItemStack) > 0) {
                    successfulTransfer = mergeInto(SlotZone.FUEL_ZONE, sourceItemStack, true);
                }
                if (!successfulTransfer) {
                    if (sourceZone == SlotZone.PLAYER_HOTBAR) { // main inventory
                        successfulTransfer = mergeInto(SlotZone.PLAYER_MAIN_INVENTORY, sourceItemStack, false);
                    } else {
                        successfulTransfer = mergeInto(SlotZone.PLAYER_HOTBAR, sourceItemStack, false);
                    }
                }
                break;

            default:
                throw new IllegalArgumentException("unexpected sourceZone:" + sourceZone);
        }
        if (!successfulTransfer) return ItemStack.EMPTY;

        if (sourceItemStack.isEmpty()) {
            sourceSlot.putStack(ItemStack.EMPTY);
        } else {
            sourceSlot.onSlotChanged();
        }

        if (sourceItemStack.getCount() == sourceStackBeforeMerge.getCount()) {
            return ItemStack.EMPTY;
        }
        sourceSlot.onTake(player, sourceItemStack);
        return sourceStackBeforeMerge;
    }

    private boolean mergeInto(SlotZone destinationZone, ItemStack sourceItemStack, boolean fillFromEnd) {
        return mergeItemStack(sourceItemStack, destinationZone.firstIndex, destinationZone.lastIndexPlus1, fillFromEnd);
    }

    public double fractionOfFuelRemaining(int fuelSlot) {
        if (furnaceStateData.burnTimeInitialValues[fuelSlot] <= 0) return 0;
        double fraction = furnaceStateData.burnTimeRemainings[fuelSlot] / (double) furnaceStateData.burnTimeInitialValues[fuelSlot];
        return MathHelper.clamp(fraction, 0.0, 1.0);
    }

    public int secondsOfFuelRemaining(int fuelSlot) {
        if (furnaceStateData.burnTimeRemainings[fuelSlot] <= 0) return 0;
        return furnaceStateData.burnTimeRemainings[fuelSlot] / 20; // 20 ticks per second
    }

    public double fractionOfCookTimeComplete() {
        if (furnaceStateData.cookTimeForCompletion == 0) return 0;
        double fraction = furnaceStateData.cookTimeElapsed / (double) furnaceStateData.cookTimeForCompletion;
        return MathHelper.clamp(fraction, 0.0, 1.0);
    }

    public static class SlotFuel extends Slot {
        public SlotFuel(IInventory inventoryIn, int index, int xPosition, int yPosition) {
            super(inventoryIn, index, xPosition, yPosition);
        }

        @Override
        public boolean isItemValid(ItemStack stack) {
            return AlloyFurnaceTileEntity.isItemValidForFuelSlot(stack);
        }
    }

    // SlotSmeltableInput is a slot for input item
    public static class SlotSmeltableInput extends Slot {
        public SlotSmeltableInput(IInventory inventoryIn, int index, int xPosition, int yPosition) {
            super(inventoryIn, index, xPosition, yPosition);
        }

        // if this function returns false, the player won't be able to insert the given item into this slot
        @Override
        public boolean isItemValid(ItemStack stack) {
            return AlloyFurnaceTileEntity.isItemValidForInputSlot(stack);
        }
    }

    // SlotOutput is a slot that will not accept any item
    public static class SlotOutput extends Slot {
        public SlotOutput(IInventory inventoryIn, int index, int xPosition, int yPosition) {
            super(inventoryIn, index, xPosition, yPosition);
        }

        // if this function returns false, the player won't be able to insert the given item into this slot
        @Override
        public boolean isItemValid(ItemStack stack) {
            return AlloyFurnaceTileEntity.isItemValidForOutputSlot(stack);
        }
    }

    private final AlloyFurnaceZoneContents inputZoneContents;
    private final AlloyFurnaceZoneContents outputZoneContents;
    private final AlloyFurnaceZoneContents fuelZoneContents;
    private final AlloyFurnaceStateData furnaceStateData;

    private final World world;

    private enum SlotZone {
        FUEL_ZONE(FIRST_FUEL_SLOT_INDEX, FUEL_SLOTS_COUNT),
        INPUT_ZONE(FIRST_INPUT_SLOT_INDEX, INPUT_SLOTS_COUNT),
        OUTPUT_ZONE(FIRST_OUTPUT_SLOT_INDEX, OUTPUT_SLOTS_COUNT),
        PLAYER_MAIN_INVENTORY(PLAYER_INVENTORY_FIRST_SLOT_INDEX, PLAYER_INVENTORY_SLOT_COUNT),
        PLAYER_HOTBAR(HOTBAR_FIRST_SLOT_INDEX, HOTBAR_SLOT_COUNT);

        SlotZone(int firstIndex, int numberOfSlots) {
            this.firstIndex = firstIndex;
            this.slotCount = numberOfSlots;
            this.lastIndexPlus1 = firstIndex + numberOfSlots;
        }

        public final int firstIndex;
        public final int slotCount;
        public final int lastIndexPlus1;

        public static SlotZone getZoneFromIndex(int slotIndex) {
            for (SlotZone slotZone : SlotZone.values()) {
                if (slotIndex >= slotZone.firstIndex && slotIndex < slotZone.lastIndexPlus1) return slotZone;
            }
            throw new IndexOutOfBoundsException("Unexpected slotIndex");
        }
    }
}

 

 

Any ideas how to fix that?

Edited by Skyriis
Link to comment
Share on other sites

Screen:

Spoiler

package de.blutmondgilde.blutmondrpg.tileentities.alloyfurnace;

import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;

@OnlyIn(Dist.CLIENT)
public class AlloyFurnaceScreen extends ContainerScreen<AlloyFurnaceContainer> {
    private final AlloyFurnaceContainer containerFurnace;

    public AlloyFurnaceScreen(AlloyFurnaceContainer containerFurnace, PlayerInventory playerInventory, ITextComponent title) {
        super(containerFurnace, playerInventory, title);
        this.containerFurnace = containerFurnace;

        // Set the width and height of the gui.  Should match the size of the texture!
        xSize = 176;
        ySize = 207;
    }

    // some [x,y] coordinates of graphical elements
    final int COOK_BAR_XPOS = 49;
    final int COOK_BAR_YPOS = 60;
    final int COOK_BAR_ICON_U = 0;   // texture position of white arrow icon [u,v]
    final int COOK_BAR_ICON_V = 207;
    final int COOK_BAR_WIDTH = 80;
    final int COOK_BAR_HEIGHT = 17;

    final int FLAME_XPOS = 54;
    final int FLAME_YPOS = 80;
    final int FLAME_ICON_U = 176;   // texture position of flame icon [u,v]
    final int FLAME_ICON_V = 0;
    final int FLAME_WIDTH = 14;
    final int FLAME_HEIGHT = 14;
    final int FLAME_X_SPACING = 18;

    public void render(int mouseX, int mouseY, float partialTicks) {
        this.renderBackground();
        super.render(mouseX, mouseY, partialTicks);
        this.renderHoveredToolTip(mouseX, mouseY);
    }

    // Draw the Tool tip text if hovering over something of interest on the screen
    protected void renderHoveredToolTip(int mouseX, int mouseY) {
        if (!this.minecraft.player.inventory.getItemStack().isEmpty())
            return;  // no tooltip if the player is dragging something

        List<String> hoveringText = new ArrayList<String>();

        // If the mouse is over the progress bar add the progress bar hovering text
        if (isInRect(guiLeft + COOK_BAR_XPOS, guiTop + COOK_BAR_YPOS, COOK_BAR_WIDTH, COOK_BAR_HEIGHT, mouseX, mouseY)) {
            hoveringText.add("Progress:");
            int cookPercentage = (int) (containerFurnace.fractionOfCookTimeComplete() * 100);
            hoveringText.add(cookPercentage + "%");
        }

        // If the mouse is over one of the burn time indicators, add the burn time indicator hovering text
        for (int i = 0; i < containerFurnace.FUEL_SLOTS_COUNT; ++i) {
            if (isInRect(guiLeft + FLAME_XPOS + FLAME_X_SPACING * i, guiTop + FLAME_YPOS, FLAME_WIDTH, FLAME_HEIGHT, mouseX, mouseY)) {
                hoveringText.add("Fuel Time:");
                hoveringText.add(containerFurnace.secondsOfFuelRemaining(i) + "s");
            }
        }

        // If hoveringText is not empty draw the hovering text.  Otherwise, use vanilla to render tooltip for the slots
        if (!hoveringText.isEmpty()) {
            renderTooltip(hoveringText, mouseX, mouseY);
        } else {
            super.renderHoveredToolTip(mouseX, mouseY);
        }
    }


    @Override
    protected void drawGuiContainerBackgroundLayer(float partialTicks, int x, int y) {
        RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
        this.minecraft.getTextureManager().bindTexture(TEXTURE);

        // width and height are the size provided to the window when initialised after creation.
        // xSize, ySize are the expected size of the texture-? usually seems to be left as a default.
        // The code below is typical for vanilla containers, so I've just copied that- it appears to centre the texture within
        //  the available window
        int edgeSpacingX = (this.width - this.xSize) / 2;
        int edgeSpacingY = (this.height - this.ySize) / 2;
        this.blit(edgeSpacingX, edgeSpacingY, 0, 0, this.xSize, this.ySize);

        // draw the cook progress bar
        double cookProgress = containerFurnace.fractionOfCookTimeComplete();
        blit(guiLeft + COOK_BAR_XPOS, guiTop + COOK_BAR_YPOS, COOK_BAR_ICON_U, COOK_BAR_ICON_V,
                (int) (cookProgress * COOK_BAR_WIDTH), COOK_BAR_HEIGHT);

        // draw the fuel remaining bar for each fuel slot flame
        for (int i = 0; i < containerFurnace.FUEL_SLOTS_COUNT; ++i) {
            double burnRemaining = containerFurnace.fractionOfFuelRemaining(i);
            int yOffset = (int) ((1.0 - burnRemaining) * FLAME_HEIGHT);
            blit(guiLeft + FLAME_XPOS + FLAME_X_SPACING * i, guiTop + FLAME_YPOS + yOffset,
                    FLAME_ICON_U, FLAME_ICON_V + yOffset, FLAME_WIDTH, FLAME_HEIGHT - yOffset);
        }
    }

    @Override
    protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
        super.drawGuiContainerForegroundLayer(mouseX, mouseY);
        final int LABEL_XPOS = 5;
        final int LABEL_YPOS = 5;
        font.drawString(title.getFormattedText(), LABEL_XPOS, LABEL_YPOS, Color.darkGray.getRGB());
    }

    // Returns true if the given x,y coordinates are within the given rectangle
    public static boolean isInRect(int x, int y, int xSize, int ySize, int mouseX, int mouseY) {
        return ((mouseX >= x && mouseX <= x + xSize) && (mouseY >= y && mouseY <= y + ySize));
    }

    // This is the resource location for the background image
    private static final ResourceLocation TEXTURE = new ResourceLocation("minecraftbyexample", "textures/gui/mbe31_inventory_furnace_bg.png");

}

 

Block:

Spoiler

package de.blutmondgilde.blutmondrpg.tileentities.alloyfurnace;

import net.minecraft.block.Block;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
import net.minecraft.block.ContainerBlock;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.state.IntegerProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.fml.network.NetworkHooks;

public class AlloyFurnaceBlockInventory extends ContainerBlock {
    public AlloyFurnaceBlockInventory() {
        super(Block.Properties.create(Material.ROCK));

        BlockState defaultBlockState = this.stateContainer.getBaseState().with(BURNING_SIDES_COUNT, 0);
        this.setDefaultState(defaultBlockState);
    }

    // --- The block changes its appearance depending on how many of the furnace slots have burning fuel in them
    //  In order to do that, we add a blockstate for each state (0 -> 4), each with a corresponding model.  We also change the blockLight emitted.

    final static int MAX_NUMBER_OF_BURNING_SIDES = 4;
    public static final IntegerProperty BURNING_SIDES_COUNT =
            IntegerProperty.create("burning_sides_count", 0, MAX_NUMBER_OF_BURNING_SIDES);

    protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) {
        builder.add(BURNING_SIDES_COUNT);
    }

    // change the furnace emitted light ("block light") depending on how many slots are burning
    private static final int ALL_SIDES_LIGHT_VALUE = 15; // light value for four sides burning
    private static final int ONE_SIDE_LIGHT_VALUE = 8;  // light value for a single side burning

    /**
     * Amount of block light emitted by the furnace
     */
    public int getLightValue(BlockState state) {
        int lightValue = 0;
        Integer burningSidesCount = state.get(BURNING_SIDES_COUNT);

        if (burningSidesCount == 0) {
            lightValue = 0;
        } else {
            // linearly interpolate the light value depending on how many slots are burning
            lightValue = ONE_SIDE_LIGHT_VALUE +
                    (ALL_SIDES_LIGHT_VALUE - ONE_SIDE_LIGHT_VALUE) * burningSidesCount / (MAX_NUMBER_OF_BURNING_SIDES - 1);
        }
        lightValue = MathHelper.clamp(lightValue, 0, ALL_SIDES_LIGHT_VALUE);
        return lightValue;
    }

    @Override
    public TileEntity createTileEntity(BlockState state, IBlockReader world) {
        return createNewTileEntity(world);
    }

    @Override
    public TileEntity createNewTileEntity(IBlockReader worldIn) {
        return new AlloyFurnaceTileEntity();
    }

    @Override
    public boolean hasTileEntity(BlockState state) {
        return true;
    }

    @Override
    public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult rayTraceResult) {
        if (world.isRemote) return ActionResultType.SUCCESS;

        INamedContainerProvider namedContainerProvider = this.getContainer(state, world, pos);
        if (namedContainerProvider != null) {
            if (!(player instanceof ServerPlayerEntity)) return ActionResultType.FAIL;

            ServerPlayerEntity serverPlayerEntity = (ServerPlayerEntity) player;
            NetworkHooks.openGui(serverPlayerEntity, namedContainerProvider, (packetBuffer) -> {
            });
        }
        return ActionResultType.SUCCESS;
    }

    @Override
    public void onReplaced(BlockState state, World world, BlockPos blockPos, BlockState newState, boolean isMoving) {
        if (state.getBlock() != newState.getBlock()) {
            TileEntity tileentity = world.getTileEntity(blockPos);
            if (tileentity instanceof AlloyFurnaceTileEntity) {
                AlloyFurnaceTileEntity tileEntityFurnace = (AlloyFurnaceTileEntity) tileentity;
                tileEntityFurnace.dropAllContents(world, blockPos);
            }
            super.onReplaced(state, world, blockPos, newState, isMoving);
        }
    }

    @Override
    public BlockRenderType getRenderType(BlockState iBlockState) {
        return BlockRenderType.MODEL;
    }
}

 

TileEntity:

Spoiler

package de.blutmondgilde.blutmondrpg.tileentities.alloyfurnace;

import de.blutmondgilde.blutmondrpg.tileentities.TileEntityList;
import de.blutmondgilde.blutmondrpg.util.SetBlockStateFlag;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.AbstractCookingRecipe;
import net.minecraft.item.crafting.FurnaceRecipe;
import net.minecraft.item.crafting.IRecipeType;
import net.minecraft.item.crafting.RecipeManager;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SUpdateTileEntityPacket;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.World;

import java.util.Optional;

public class AlloyFurnaceTileEntity extends TileEntity implements INamedContainerProvider, ITickableTileEntity {

    public static final int FUEL_SLOTS_COUNT = 4;
    public static final int INPUT_SLOTS_COUNT = 5;
    public static final int OUTPUT_SLOTS_COUNT = 5;
    public static final int TOTAL_SLOTS_COUNT = FUEL_SLOTS_COUNT + INPUT_SLOTS_COUNT + OUTPUT_SLOTS_COUNT;

    private final AlloyFurnaceZoneContents fuelZoneContents;
    private final AlloyFurnaceZoneContents inputZoneContents;
    private final AlloyFurnaceZoneContents outputZoneContents;

    private final AlloyFurnaceStateData furnaceStateData = new AlloyFurnaceStateData();

    public AlloyFurnaceTileEntity() {
        super(TileEntityList.ALLOY_FURNACE.get());
        fuelZoneContents = AlloyFurnaceZoneContents.createForTileEntity(FUEL_SLOTS_COUNT,
                this::canPlayerAccessInventory, this::markDirty);
        inputZoneContents = AlloyFurnaceZoneContents.createForTileEntity(INPUT_SLOTS_COUNT,
                this::canPlayerAccessInventory, this::markDirty);
        outputZoneContents = AlloyFurnaceZoneContents.createForTileEntity(OUTPUT_SLOTS_COUNT,
                this::canPlayerAccessInventory, this::markDirty);
    }

    public boolean canPlayerAccessInventory(PlayerEntity player) {
        if (this.world.getTileEntity(this.pos) != this) return false;
        final double X_CENTRE_OFFSET = 0.5;
        final double Y_CENTRE_OFFSET = 0.5;
        final double Z_CENTRE_OFFSET = 0.5;
        final double MAXIMUM_DISTANCE_SQ = 8.0 * 8.0;
        return player.getDistanceSq(pos.getX() + X_CENTRE_OFFSET, pos.getY() + Y_CENTRE_OFFSET, pos.getZ() + Z_CENTRE_OFFSET) < MAXIMUM_DISTANCE_SQ;
    }

    public int numberOfBurningFuelSlots() {
        int burningCount = 0;
        for (int burnTime : furnaceStateData.burnTimeRemainings) {
            if (burnTime > 0) ++burningCount;
        }
        return burningCount;
    }

    @Override
    public void tick() {
        if (world.isRemote) return; // do nothing on client.
        ItemStack currentlySmeltingItem = getCurrentlySmeltingInputItem();

        if (!ItemStack.areItemsEqual(currentlySmeltingItem, currentlySmeltingItemLastTick)) {  // == and != don't work!
            furnaceStateData.cookTimeElapsed = 0;
        }
        currentlySmeltingItemLastTick = currentlySmeltingItem.copy();

        if (!currentlySmeltingItem.isEmpty()) {
            int numberOfFuelBurning = burnFuel();

            if (numberOfFuelBurning > 0) {
                furnaceStateData.cookTimeElapsed += numberOfFuelBurning;
            } else {
                furnaceStateData.cookTimeElapsed -= 2;
            }
            if (furnaceStateData.cookTimeElapsed < 0) furnaceStateData.cookTimeElapsed = 0;

            int cookTimeForCurrentItem = getCookTime(this.world, currentlySmeltingItem);
            furnaceStateData.cookTimeForCompletion = cookTimeForCurrentItem;
            if (furnaceStateData.cookTimeElapsed >= cookTimeForCurrentItem) {
                smeltFirstSuitableInputItem();
                furnaceStateData.cookTimeElapsed = 0;
            }
        } else {
            furnaceStateData.cookTimeElapsed = 0;
        }

        int numberBurning = numberOfBurningFuelSlots();
        BlockState currentBlockState = world.getBlockState(this.pos);
        BlockState newBlockState = currentBlockState.with(AlloyFurnaceBlockInventory.BURNING_SIDES_COUNT, numberBurning);
        if (!newBlockState.equals(currentBlockState)) {
            final int FLAGS = SetBlockStateFlag.get(SetBlockStateFlag.BLOCK_UPDATE, SetBlockStateFlag.SEND_TO_CLIENTS);
            world.setBlockState(this.pos, newBlockState, FLAGS);
            markDirty();
        }
    }

    private int burnFuel() {
        int burningCount = 0;
        boolean inventoryChanged = false;

        for (int fuelIndex = 0; fuelIndex < FUEL_SLOTS_COUNT; fuelIndex++) {
            if (furnaceStateData.burnTimeRemainings[fuelIndex] > 0) {
                --furnaceStateData.burnTimeRemainings[fuelIndex];
                ++burningCount;
            }

            if (furnaceStateData.burnTimeRemainings[fuelIndex] == 0) {
                ItemStack fuelItemStack = fuelZoneContents.getStackInSlot(fuelIndex);
                if (!fuelItemStack.isEmpty() && getItemBurnTime(this.world, fuelItemStack) > 0) {
                    int burnTimeForItem = getItemBurnTime(this.world, fuelItemStack);
                    furnaceStateData.burnTimeRemainings[fuelIndex] = burnTimeForItem;
                    furnaceStateData.burnTimeInitialValues[fuelIndex] = burnTimeForItem;
                    fuelZoneContents.decrStackSize(fuelIndex, 1);
                    ++burningCount;
                    inventoryChanged = true;

                    if (fuelItemStack.isEmpty()) {
                        ItemStack containerItem = fuelItemStack.getContainerItem();
                        fuelZoneContents.setInventorySlotContents(fuelIndex, containerItem);
                    }
                }
            }
        }
        if (inventoryChanged) markDirty();
        return burningCount;
    }

    private ItemStack getCurrentlySmeltingInputItem() {
        return smeltFirstSuitableInputItem(false);
    }

    private void smeltFirstSuitableInputItem() {
        smeltFirstSuitableInputItem(true);
    }

    private ItemStack smeltFirstSuitableInputItem(boolean performSmelt) {
        Integer firstSuitableInputSlot = null;
        Integer firstSuitableOutputSlot = null;
        ItemStack result = ItemStack.EMPTY;

        for (int inputIndex = 0; inputIndex < INPUT_SLOTS_COUNT; inputIndex++) {
            ItemStack itemStackToSmelt = inputZoneContents.getStackInSlot(inputIndex);
            if (!itemStackToSmelt.isEmpty()) {
                result = getSmeltingResultForItem(this.world, itemStackToSmelt);
                if (!result.isEmpty()) {
                    for (int outputIndex = 0; outputIndex < OUTPUT_SLOTS_COUNT; outputIndex++) {
                        if (willItemStackFit(outputZoneContents, outputIndex, result)) {
                            firstSuitableInputSlot = inputIndex;
                            firstSuitableOutputSlot = outputIndex;
                            break;
                        }
                    }
                    if (firstSuitableInputSlot != null) break;
                }
            }
        }

        if (firstSuitableInputSlot == null) return ItemStack.EMPTY;

        ItemStack returnvalue = inputZoneContents.getStackInSlot(firstSuitableInputSlot).copy();
        if (!performSmelt) return returnvalue;

        inputZoneContents.decrStackSize(firstSuitableInputSlot, 1);
        outputZoneContents.increaseStackSize(firstSuitableOutputSlot, result);

        markDirty();
        return returnvalue;
    }

    public boolean willItemStackFit(AlloyFurnaceZoneContents furnaceZoneContents, int slotIndex, ItemStack itemStackOrigin) {
        ItemStack itemStackDestination = furnaceZoneContents.getStackInSlot(slotIndex);

        if (itemStackDestination.isEmpty() || itemStackOrigin.isEmpty()) {
            return true;
        }

        if (!itemStackOrigin.isItemEqual(itemStackDestination)) {
            return false;
        }

        int sizeAfterMerge = itemStackDestination.getCount() + itemStackOrigin.getCount();
        return sizeAfterMerge <= furnaceZoneContents.getInventoryStackLimit() && sizeAfterMerge <= itemStackDestination.getMaxStackSize();
    }

    public static ItemStack getSmeltingResultForItem(World world, ItemStack itemStack) {
        Optional<FurnaceRecipe> matchingRecipe = getMatchingRecipeForInput(world, itemStack);
        return matchingRecipe.map(furnaceRecipe -> furnaceRecipe.getRecipeOutput().copy()).orElse(ItemStack.EMPTY);
    }

    public static int getItemBurnTime(World world, ItemStack stack) {
        int burntime = net.minecraftforge.common.ForgeHooks.getBurnTime(stack);
        return burntime;
    }

    public static Optional<FurnaceRecipe> getMatchingRecipeForInput(World world, ItemStack itemStack) {
        RecipeManager recipeManager = world.getRecipeManager();
        Inventory singleItemInventory = new Inventory(itemStack);
        Optional<FurnaceRecipe> matchingRecipe = recipeManager.getRecipe(IRecipeType.SMELTING, singleItemInventory, world);
        return matchingRecipe;
    }

    public static int getCookTime(World world, ItemStack itemStack) {
        Optional<FurnaceRecipe> matchingRecipe = getMatchingRecipeForInput(world, itemStack);
        return matchingRecipe.map(AbstractCookingRecipe::getCookTime).orElse(0);
    }

    static public boolean isItemValidForFuelSlot(ItemStack itemStack) {
        return true;
    }

    static public boolean isItemValidForInputSlot(ItemStack itemStack) {
        return true;
    }

    static public boolean isItemValidForOutputSlot(ItemStack itemStack) {
        return false;
    }

    private final String FUEL_SLOTS_NBT = "fuelSlots";
    private final String INPUT_SLOTS_NBT = "inputSlots";
    private final String OUTPUT_SLOTS_NBT = "outputSlots";

    @Override
    public CompoundNBT write(CompoundNBT parentNBTTagCompound) {
        super.write(parentNBTTagCompound); // The super call is required to save and load the tile's location

        furnaceStateData.putIntoNBT(parentNBTTagCompound);
        parentNBTTagCompound.put(FUEL_SLOTS_NBT, fuelZoneContents.serializeNBT());
        parentNBTTagCompound.put(INPUT_SLOTS_NBT, inputZoneContents.serializeNBT());
        parentNBTTagCompound.put(OUTPUT_SLOTS_NBT, outputZoneContents.serializeNBT());
        return parentNBTTagCompound;
    }

    @Override
    public void read(CompoundNBT nbtTagCompound) {
        super.read(nbtTagCompound);

        furnaceStateData.readFromNBT(nbtTagCompound);

        CompoundNBT inventoryNBT = nbtTagCompound.getCompound(FUEL_SLOTS_NBT);
        fuelZoneContents.deserializeNBT(inventoryNBT);

        inventoryNBT = nbtTagCompound.getCompound(INPUT_SLOTS_NBT);
        inputZoneContents.deserializeNBT(inventoryNBT);

        inventoryNBT = nbtTagCompound.getCompound(OUTPUT_SLOTS_NBT);
        outputZoneContents.deserializeNBT(inventoryNBT);

        if (fuelZoneContents.getSizeInventory() != FUEL_SLOTS_COUNT
                || inputZoneContents.getSizeInventory() != INPUT_SLOTS_COUNT
                || outputZoneContents.getSizeInventory() != OUTPUT_SLOTS_COUNT
        )
            throw new IllegalArgumentException("Corrupted NBT: Number of inventory slots did not match expected.");
    }

    @Override
    public SUpdateTileEntityPacket getUpdatePacket() {
        CompoundNBT updateTagDescribingTileEntityState = getUpdateTag();
        final int METADATA = 42; // arbitrary.
        return new SUpdateTileEntityPacket(this.pos, METADATA, updateTagDescribingTileEntityState);
    }

    @Override
    public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) {
        CompoundNBT updateTagDescribingTileEntityState = pkt.getNbtCompound();
        handleUpdateTag(updateTagDescribingTileEntityState);
    }

    @Override
    public CompoundNBT getUpdateTag() {
        CompoundNBT nbtTagCompound = new CompoundNBT();
        write(nbtTagCompound);
        return nbtTagCompound;
    }

    @Override
    public void handleUpdateTag(CompoundNBT tag) {
        read(tag);
    }

    public void dropAllContents(World world, BlockPos blockPos) {
        InventoryHelper.dropInventoryItems(world, blockPos, fuelZoneContents);
        InventoryHelper.dropInventoryItems(world, blockPos, inputZoneContents);
        InventoryHelper.dropInventoryItems(world, blockPos, outputZoneContents);
    }

    @Override
    public ITextComponent getDisplayName() {
        return new TranslationTextComponent("container.minecraftbyexample.mbe31_container_registry_name");
    }

    @Override
    public Container createMenu(int windowID, PlayerInventory playerInventory, PlayerEntity playerEntity) {
        return AlloyFurnaceContainer.createContainerServerSide(windowID, playerInventory,
                inputZoneContents, outputZoneContents, fuelZoneContents, furnaceStateData);
    }

    private ItemStack currentlySmeltingItemLastTick = ItemStack.EMPTY;
}

 

 

Link to comment
Share on other sites

59 minutes ago, Skyriis said:

private void clientSetup(final FMLClientSetupEvent e) { ScreenManager.registerFactory(ContainerList.ALLOY_FURNACE.get(), AlloyFurnaceScreen::new); }

I thought i'm register my screen here.

 

#edit

clientSetup is called from the Mod Constructor using:

MinecraftForge.EVENT_BUS.addListener(this::clientSetup);

and the container is registered using the DeferredRegistrer class

private static final DeferredRegister<ContainerType<?>> CONTAINER_REGISTRY = new DeferredRegister<>(ForgeRegistries.CONTAINERS, Ref.MOD_ID);
    public static final RegistryObject<ContainerType<AlloyFurnaceContainer>> ALLOY_FURNACE = CONTAINER_REGISTRY.register("alloy_furnace_container", () -> IForgeContainerType.create(AlloyFurnaceContainer::createContainerClientSide));

    public static void register() {
        CONTAINER_REGISTRY.register(FMLJavaModLoadingContext.get().getModEventBus());
        Ref.LOGGER.debug("Registered Container.");
    }

 

Edited by Skyriis
Link to comment
Share on other sites

44 minutes ago, diesieben07 said:

That is the wrong event bus.

So if i add:

MinecraftForge.EVENT_BUS.register(this);

and change clientSetup to:

@SubscribeEvent
    public void clientSetup(final FMLClientSetupEvent e) {
        ScreenManager.registerFactory(ContainerList.ALLOY_FURNACE.get(), AlloyFurnaceScreen::new);
        Ref.LOGGER.debug("Screens Registered");
    }

it should work?

#Edit:

after a bit testing this works:

@EventBusSubscriber(modid = Ref.MOD_ID, bus = EventBusSubscriber.Bus.MOD)
public class ScreenHandler {
    @SubscribeEvent
    public static void clientSetup(final FMLClientSetupEvent e) {
        ScreenManager.registerFactory(ContainerList.ALLOY_FURNACE.get(), AlloyFurnaceScreen::new);
        Ref.LOGGER.debug("Screens Registered");
    }
}

 

Thanks for the Help! :D

Edited by Skyriis
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.