Jump to content

Container Problem [1.16.5]


Yurim64

Recommended Posts

Hi!
I was creating a simil-furnace block with his own TileEntity, Gui and Container.
While creating it, I see the vanilla code and noticed that the FurnaceScreen scall read the lit progress by the FurnaceContainer, that stores the data by an IIntArray object.
I tryed to recreate this scenario, but my IIntArray is not syncronized with the TileEntity... any suggestions?
Here is the classes:
The Block:

Spoiler

public class HobBlock extends Block {

    private static final VoxelShape SHAPE_NORTH = Block.box(0, 0, 0, 16, 16, 16);
    private static final VoxelShape SHAPE_WEST = Block.box(0, 0, 0, 16, 16, 16);

    public static final DirectionProperty FACING = DirectionProperty.create("facing", Direction.Plane.HORIZONTAL);
    public static final BooleanProperty ON = BooleanProperty.create("on");

    public HobBlock() {
        super(Properties.of(Material.METAL).strength(2.5f));
        this.registerDefaultState(stateDefinition.any().setValue(FACING, Direction.NORTH).setValue(ON, false));
    }

    @Override
    public ActionResultType use(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult rayTraceResult) {
        if (world.isClientSide)
            return ActionResultType.SUCCESS;
        //world.setBlock(pos, state.setValue(ON, !state.getValue(ON)), 3);
        TileEntity blockEntity = world.getBlockEntity(pos);
        if (blockEntity instanceof HobTileEntity) {
            player.openMenu(((HobTileEntity) blockEntity));
            player.awardStat(Stats.INTERACT_WITH_FURNACE);
            return ActionResultType.CONSUME;
        }
        return ActionResultType.PASS;//super.use(state, world, pos, player, hand, rayTraceResult);
    }

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

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

    @Override
    protected void createBlockStateDefinition(StateContainer.Builder<Block, BlockState> builder) {
        builder.add(FACING, ON);
    }

    @Nullable
    @Override
    public BlockState getStateForPlacement(BlockItemUseContext context) {
        return this.defaultBlockState().setValue(FACING, context.getHorizontalDirection()).setValue(ON, false);
    }

    @Override
    public BlockState rotate(BlockState state, IWorld world, BlockPos pos, Rotation direction) {
        return state.setValue(FACING, direction.rotate(state.getValue(FACING)));
    }

    @Override
    public BlockState mirror(BlockState state, Mirror mirror) {
        return state.setValue(FACING, mirror.mirror(state.getValue(FACING)));
    }

    @Override
    public VoxelShape getShape(BlockState state, IBlockReader reader, BlockPos pos, ISelectionContext context) {
        Direction value = state.getValue(FACING);
        switch (value) {
            case SOUTH:
            case NORTH:
                return SHAPE_NORTH;
            case WEST:
            case EAST:
                return SHAPE_WEST;
        }
        return null;
    }

    @Override
    public BlockRenderType getRenderShape(BlockState state) {
        return BlockRenderType.MODEL;
    }

    @Override
    public void animateTick(BlockState state, World world, BlockPos pos, Random random) {
        super.animateTick(state, world, pos, random);
        if (state.getValue(ON)) {
            for (int i = 0; i < 10; i++) {
                double xOff = random.nextDouble() * (random.nextBoolean() ? -1 : 1);
                double zOff = random.nextDouble() * (random.nextBoolean() ? -1 : 1);
                world.addParticle(ParticleTypes.SMOKE, pos.getX() + xOff, pos.getY() + 1, pos.getZ() + zOff, 0, 0.1, 0.1);
            }
        }
    }
}

 

The TileEntity:

Spoiler

public class HobTileEntity extends TileEntity implements INamedContainerProvider, IInventory, ITickableTileEntity {

    private final IIntArray timerData = new IIntArray() {
        public int get(int index) {
            System.out.println(timers);
            if (index > HobTileEntity.this.timers.size())
                return -1;
            return HobTileEntity.this.timers.get(index);
        }

        public void set(int index, int value) {
            if (index > HobTileEntity.this.timers.size())
                return;
            HobTileEntity.this.timers.set(index, value);
        }

        public int getCount() {
            return 4;
        }
    };

    public HobTileEntity() {
        super(RegistryHandler.HOB_TILE_ENTITY.get());
        this.inventory = NonNullList.withSize(4, ItemStack.EMPTY);
        this.timers = NonNullList.withSize(4, -1);
    }

    //Tile Entity Stuff

    @Override
    public CompoundNBT save(CompoundNBT nbt) {
        super.save(nbt);
        ItemStackHelper.saveAllItems(nbt, inventory);
        nbt.putIntArray("timers", timers);
        return nbt;
    }

    @Override
    public void load(BlockState state, CompoundNBT nbt) {
        super.load(state, nbt);
        ItemStackHelper.loadAllItems(nbt, inventory);
        int[] ts = nbt.getIntArray("timers");
        if (ts.length < 1) {
            System.out.println("Invalid timers saved");
            return;
        }
        this.timers = NonNullList.withSize(4, -1);
        for (int i = 0; i < timers.size(); i++) {
            timers.set(i, ts[i]);
        }
    }

    @Override
    public void tick() {
        for (int i = 0; i < this.getContainerSize(); i++) {
            ItemStack stack = inventory.get(i);
            if (stack.isEmpty())
                continue;
            int timer = timers.get(i);
            if (timer == -1 && isCookable(stack)) {
                timers.set(i, 0);
            } else if (timer < 100) {
                timers.set(i, timer + 1);
            } else if (timer == 100) {
                timers.set(i, -1);
                inventory.set(i, new ItemStack(Items.DIAMOND));
            }
        }
    }

    private boolean isCookable(ItemStack stack) {
        if (stack.isEmpty())
            return false;
        return true;
    }

    public NonNullList<Integer> getTimers() {
        return this.timers;
    }

    //Container Stuff

    @Override
    public ITextComponent getDisplayName() {
        return new TranslationTextComponent("kitchen.display.hob");
    }

    @Nullable
    @Override
    public Container createMenu(int id, PlayerInventory inventory, PlayerEntity player) {
        return HobContainer.defaultContainer(id, this, inventory, this.timerData);
    }

    //Inventory Stuff

    private NonNullList<ItemStack> inventory;
    private NonNullList<Integer> timers;

    @Override
    public int getContainerSize() {
        return inventory.size();
    }

    @Override
    public boolean isEmpty() {
        return inventory.isEmpty();
    }

    @Override
    public ItemStack getItem(int index) {
        return inventory.get(index);
    }

    @Override
    public ItemStack removeItem(int index, int quantity) {
        ItemStack stack = getItem(index);
        if (!stack.isEmpty()) {
            int rest = stack.getCount() - quantity;
            if (rest <= 0) {
                inventory.set(index, ItemStack.EMPTY);
                return stack;
            } else {
                stack.setCount(rest);
                return new ItemStack(stack.getItem(), quantity);
            }
        }
        return ItemStack.EMPTY;
    }

    @Override
    public ItemStack removeItemNoUpdate(int index) {
        return inventory.remove(index);
    }

    @Override
    public void setItem(int index, ItemStack stack) {
        inventory.set(index, stack);
    }

    @Override
    public boolean stillValid(PlayerEntity player) {
        return true;
    }

    @Override
    public void clearContent() {
        inventory.clear();
    }
}

 

The Container:

Spoiler

public class HobContainer extends Container {

    public static HobContainer defaultContainer(int id, PlayerInventory inventory) {
        return new HobContainer(id, new Inventory(4), inventory, new IntArray(4));
    }

    public static HobContainer defaultContainer(int id, IInventory inventory, PlayerInventory playerInventory, IIntArray timers) {
        return new HobContainer(id, inventory, playerInventory, timers);
    }

    private IInventory entityInventory;
    private IIntArray timers;

    public HobContainer(int id, IInventory inventory, PlayerInventory playerInventory, IIntArray timers) {
        super(RegistryHandler.HOB_CONTAINER.get(), id);
        this.entityInventory = inventory;
        this.timers = timers;
        this.addSlot(new Slot(inventory, 0, 30, 22));
        this.addSlot(new Slot(inventory, 1, 138, 22));
        this.addSlot(new Slot(inventory, 2, 84, 22));
        this.addSlot(new Slot(inventory, 3, 84, 59));

        int index = 0;
        for (int i = 0; i < 9; i++) {
            this.addSlot(new Slot(playerInventory, index++, 12 + (18 * i), 145));
        }

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 9; j++) {
                this.addSlot(new Slot(playerInventory, index++, 12 + (18 * j), 87 + (i * 18)));
            }
        }
    }

    @Override
    public boolean stillValid(PlayerEntity player) {
        return this.entityInventory.stillValid(player);
    }

    public int getTimer(int index) {
        if (entityInventory instanceof HobTileEntity) {
            System.out.println("Correct Tile Entity");
        }
        return this.timers.get(index);
    }

    @Override
    public ItemStack quickMoveStack(PlayerEntity player, int index) {
        return ItemStack.EMPTY;
    }
}

 

The Gui:

Spoiler

public class HobGui extends ContainerScreen<HobContainer> implements IHasContainer<HobContainer> {

    private static final ResourceLocation CONTAINER_BACKGROUND = new ResourceLocation(KitchenMod.MODID, "textures/gui/hob_gui.png");

    public HobGui(HobContainer container, PlayerInventory inventory, ITextComponent title) {
        super(container, inventory, title);
        this.imageHeight = 168;
        this.imageWidth = 183;
        this.inventoryLabelY = 75;
        //this.inventoryLabelX += 5;
        this.passEvents = false;
    }

    @Override
    public void render(MatrixStack matrix, int n1, int n2, float n3) {
        this.renderBackground(matrix);
        super.render(matrix, n1, n2, n3);
        this.renderTooltip(matrix, n1, n2);
    }

    @Override
    protected void renderBg(MatrixStack matrix, float f1, int f2, int f3) {
        RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
        this.minecraft.getTextureManager().bind(CONTAINER_BACKGROUND);
        int i = (this.width - this.imageWidth) / 2;
        int j = (this.height - this.imageHeight) / 2;
        blit(matrix, i, j, 0, 0, this.imageWidth, this.imageHeight);

        //Width: 2, Height: 18 -> 18 = x * 100 -> 18/100 = x -> x = 0.18
        //Timer: 0 -> 100
        //Cords: 24, 26 -> 24, 9
        int t1 = this.menu.getTimer(0);
        int t2 = this.menu.getTimer(1);
        int t3 = this.menu.getTimer(2);
        int t4 = this.menu.getTimer(3);
        //System.out.println(String.format("%d, %d, %d, %d", t1, t2, t3, t4));
        if (t1 != -1) {
            int height = (int) (t1 * 0.18);
            blit(matrix, i + 24, j + (38 - height), 184, 18 - height, 3, 18);
        }
        if (t2 != -1) {
            int height = (int) (t2 * 0.18);
            blit(matrix, i + 132, j + 38 - height, 184, 18 - height, 3, 18);
        }
        if (t3 != -1) {
            int height = (int) (t3 * 0.18);
            blit(matrix, i + 78, j + 38 - height, 184, 18 - height, 3, 18);
        }
        if (t4 != -1) {
            int height = (int) (t4 * 0.18);
            blit(matrix, i + 78, j + 75 - height, 184, 18 - height, 3, 18);
        }
    }
}

 

The problem is that the function getTimer should call the IIntArray object of the HobTileEntity, but it seems to be only the default value from the method HobContainer.defaultContainer(int id, PlayerInventory player);
Someone has any idea?

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.