Jump to content

[1.14.4] Best way to sync progress in tile entity.


Legenes

Recommended Posts

Hi!

I was thinking about making a machine that generates RF from fuels, and it should display its current progress of burning. My problem is that I don't know the best way to sync up the tile with the GUI. Should I use a custom capability or just a packet of some kind? If I should use one of them, what should I implement? Thanks for the help!

procedure WakeMeUp(Integer plusTime);
var
  I: Integer;
begin
  for I := 0 to plusTime do begin
    println('One more minute!');
    Sleep(1000);
  end;
  println('Okay, nothing to worry, I''m alive!');
  println('So... somebody can give me a coffee?');
  println('I know it''s Pascal, and not Java, but I love it :D.');
end;
Link to comment
Share on other sites

You don't need to sync very much or very often. The client, provided that the amount of fuel has been synced as the result of an inventory change, can calculate the RF conversion process all on its own using the exact same code as the server side tile entity. There is no point or need to sync the progress.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

2 minutes ago, Draco18s said:

You don't need to sync very much or very often. The client, provided that the amount of fuel has been synced as the result of an inventory change, can calculate the RF conversion process all on its own using the exact same code as the server side tile entity. There is no point or need to sync the progress.

Sorry, I may have said something incorrectly. This block is like a furnace but without an output. I want to be able to see how much more the item inside is going to last as a fuel, like the little flame in the furnace. That depends on the currently burnt item's burn time (where the exampleItemStack.getBurnTime() always returns -1 for some reason) and how many ticks did I burn it for. I want to sync the the little flame if you get what I mean.

procedure WakeMeUp(Integer plusTime);
var
  I: Integer;
begin
  for I := 0 to plusTime do begin
    println('One more minute!');
    Sleep(1000);
  end;
  println('Okay, nothing to worry, I''m alive!');
  println('So... somebody can give me a coffee?');
  println('I know it''s Pascal, and not Java, but I love it :D.');
end;
Link to comment
Share on other sites

2 minutes ago, Legenes said:

exampleItemStack.getBurnTime() always returns -1 for some reason

I found this in the IForgeItem class:

    /**
     * @return the fuel burn time for this itemStack in a furnace. Return 0 to make
     *         it not act as a fuel. Return -1 to let the default vanilla logic
     *         decide.
     */
    default int getBurnTime(ItemStack itemStack)
    {
        return -1;
    }

I don't know if the "vanilla" logic is failing, or I need to use something else, but this is weird.

procedure WakeMeUp(Integer plusTime);
var
  I: Integer;
begin
  for I := 0 to plusTime do begin
    println('One more minute!');
    Sleep(1000);
  end;
  println('Okay, nothing to worry, I''m alive!');
  println('So... somebody can give me a coffee?');
  println('I know it''s Pascal, and not Java, but I love it :D.');
end;
Link to comment
Share on other sites

2 minutes ago, Legenes said:

I found this in the IForgeItem class:


    /**
     * @return the fuel burn time for this itemStack in a furnace. Return 0 to make
     *         it not act as a fuel. Return -1 to let the default vanilla logic
     *         decide.
     */
    default int getBurnTime(ItemStack itemStack)
    {
        return -1;
    }

I don't know if the "vanilla" logic is failing, or I need to use something else, but this is weird.

I found out that it's most likely that I need to use the

net.minecraftforge.common.ForgeHooks.getBurnTime()

instead.

procedure WakeMeUp(Integer plusTime);
var
  I: Integer;
begin
  for I := 0 to plusTime do begin
    println('One more minute!');
    Sleep(1000);
  end;
  println('Okay, nothing to worry, I''m alive!');
  println('So... somebody can give me a coffee?');
  println('I know it''s Pascal, and not Java, but I love it :D.');
end;
Link to comment
Share on other sites

47 minutes ago, diesieben07 said:

Look at what the vanilla furnace does (AbstractFurnaceContainer).

I tried to pass an IIntArray as the vanilla container does, with the values I need, I save it in a variable and I use this.trackIntArray(), but it only updates when I open the block. Am I missing something?

    private IIntArray fields;

    public MachineBlockContainer(int id, World clientWorld, BlockPos pos, PlayerInventory playerInv, PlayerEntity player, IIntArray Fields) {
        super(MachineBlock_Container, id);
		//* other stuff *//
        fields = Fields;
		//* other stuff *//

        this.trackIntArray(Fields);
    }

 

Edited by Legenes
procedure WakeMeUp(Integer plusTime);
var
  I: Integer;
begin
  for I := 0 to plusTime do begin
    println('One more minute!');
    Sleep(1000);
  end;
  println('Okay, nothing to worry, I''m alive!');
  println('So... somebody can give me a coffee?');
  println('I know it''s Pascal, and not Java, but I love it :D.');
end;
Link to comment
Share on other sites

41 minutes ago, Legenes said:

I don't know if the "vanilla" logic is failing, or I need to use something else, but this is weird.

Items, in general, by default, are not furnace fuel. If an item is fuel, it will override that method.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Just now, Draco18s said:

Items, in general, by default, are not furnace fuel. If an item is fuel, it will override that method.

 

39 minutes ago, Legenes said:

I found out that it's most likely that I need to use the


net.minecraftforge.common.ForgeHooks.getBurnTime()

instead.

I figured it out, and now I use the correct method, but thanks anyway ☺️. (It works.)

procedure WakeMeUp(Integer plusTime);
var
  I: Integer;
begin
  for I := 0 to plusTime do begin
    println('One more minute!');
    Sleep(1000);
  end;
  println('Okay, nothing to worry, I''m alive!');
  println('So... somebody can give me a coffee?');
  println('I know it''s Pascal, and not Java, but I love it :D.');
end;
Link to comment
Share on other sites

Just now, diesieben07 said:

... unless it is a vanilla fuel item. Which is why you need to call the method in ForgeHooks.

Well, yes. Because vanilla did things in a way that aren't extendable. I'm not debating that. I'm saying that the method is returning a sensible value and that it's the wrong thing to look at.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

6 minutes ago, Legenes said:

I tried to pass an IIntArray as the vanilla container does, with the values I need, I save it in a variable and I use this.trackIntArray(), but it only updates when I open the block. Am I missing something?


    private IIntArray fields;

    public MachineBlockContainer(int id, World clientWorld, BlockPos pos, PlayerInventory playerInv, PlayerEntity player, IIntArray Fields) {
        super(MachineBlock_Container, id);
		//* other stuff *//
        fields = Fields;
		//* other stuff *//

        this.trackIntArray(Fields);
    }

 

It super weird... the values are only updated when the GUI is opened, after that it doesn't track them.

procedure WakeMeUp(Integer plusTime);
var
  I: Integer;
begin
  for I := 0 to plusTime do begin
    println('One more minute!');
    Sleep(1000);
  end;
  println('Okay, nothing to worry, I''m alive!');
  println('So... somebody can give me a coffee?');
  println('I know it''s Pascal, and not Java, but I love it :D.');
end;
Link to comment
Share on other sites

Just now, diesieben07 said:

Show your implementation of IIntArray.

Well... I have this only:

    private IIntArray fields = new IntArray(2);

This is in my TileEntity's class.

procedure WakeMeUp(Integer plusTime);
var
  I: Integer;
begin
  for I := 0 to plusTime do begin
    println('One more minute!');
    Sleep(1000);
  end;
  println('Okay, nothing to worry, I''m alive!');
  println('So... somebody can give me a coffee?');
  println('I know it''s Pascal, and not Java, but I love it :D.');
end;
Link to comment
Share on other sites

1 minute ago, Legenes said:

Well... I have this only:


    private IIntArray fields = new IntArray(2);

This is in my TileEntity's class.

Okay, so I need to implement my own IIntArray, I'm so dumb, sry. I didn't look at the AbstractFurnaceTileEntity.

procedure WakeMeUp(Integer plusTime);
var
  I: Integer;
begin
  for I := 0 to plusTime do begin
    println('One more minute!');
    Sleep(1000);
  end;
  println('Okay, nothing to worry, I''m alive!');
  println('So... somebody can give me a coffee?');
  println('I know it''s Pascal, and not Java, but I love it :D.');
end;
Link to comment
Share on other sites

1 minute ago, diesieben07 said:

IntArray is not a minecraft class...

It is, but I get the point.

import net.minecraft.util.IntArray;

 

procedure WakeMeUp(Integer plusTime);
var
  I: Integer;
begin
  for I := 0 to plusTime do begin
    println('One more minute!');
    Sleep(1000);
  end;
  println('Okay, nothing to worry, I''m alive!');
  println('So... somebody can give me a coffee?');
  println('I know it''s Pascal, and not Java, but I love it :D.');
end;
Link to comment
Share on other sites

Finally, here's my working implementation:

    private final IIntArray fields = new IIntArray() {
        public int get(int index) {
            switch(index) {
                case 0:
                    return MachineBlockTile.this.counter;
              case 1:
                    return MachineBlockTile.this.burnTime;
                default:
                    return 0;
            }
        }

        public void set(int index, int value) {
            switch(index) {
                case 0:
                    MachineBlockTile.this.counter = value;
                	break;
                case 1:
                    MachineBlockTile.this.burnTime = value;
                    break;
            }

        }

        public int size() {
            return 2;
        }
    };

Thanks for the help!

Edited by Legenes
procedure WakeMeUp(Integer plusTime);
var
  I: Integer;
begin
  for I := 0 to plusTime do begin
    println('One more minute!');
    Sleep(1000);
  end;
  println('Okay, nothing to worry, I''m alive!');
  println('So... somebody can give me a coffee?');
  println('I know it''s Pascal, and not Java, but I love it :D.');
end;
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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • They were already updated, and just to double check I even did a cleanup and fresh update from that same page. I'm quite sure drivers are not the problem here. 
    • i tried downloading the drivers but it says no AMD graphics hardware has been detected    
    • Update your AMD/ATI drivers - get the drivers from their website - do not update via system  
    • As the title says i keep on crashing on forge 1.20.1 even without any mods downloaded, i have the latest drivers (nvidia) and vanilla minecraft works perfectly fine for me logs: https://pastebin.com/5UR01yG9
    • Hello everyone, I'm making this post to seek help for my modded block, It's a special block called FrozenBlock supposed to take the place of an old block, then after a set amount of ticks, it's supposed to revert its Block State, Entity, data... to the old block like this :  The problem I have is that the system breaks when handling multi blocks (I tried some fix but none of them worked) :  The bug I have identified is that the function "setOldBlockFields" in the item's "setFrozenBlock" function gets called once for the 1st block of multiblock getting frozen (as it should), but gets called a second time BEFORE creating the first FrozenBlock with the data of the 1st block, hence giving the same data to the two FrozenBlock :   Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=head] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@73681674 BlockEntityData : id:"minecraft:bed",x:3,y:-60,z:-6} Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=3, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=2, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} here is the code inside my custom "freeze" item :    @Override     public @NotNull InteractionResult useOn(@NotNull UseOnContext pContext) {         if (!pContext.getLevel().isClientSide() && pContext.getHand() == InteractionHand.MAIN_HAND) {             BlockPos blockPos = pContext.getClickedPos();             BlockPos secondBlockPos = getMultiblockPos(blockPos, pContext.getLevel().getBlockState(blockPos));             if (secondBlockPos != null) {                 createFrozenBlock(pContext, secondBlockPos);             }             createFrozenBlock(pContext, blockPos);             return InteractionResult.SUCCESS;         }         return super.useOn(pContext);     }     public static void createFrozenBlock(UseOnContext pContext, BlockPos blockPos) {         BlockState oldState = pContext.getLevel().getBlockState(blockPos);         BlockEntity oldBlockEntity = oldState.hasBlockEntity() ? pContext.getLevel().getBlockEntity(blockPos) : null;         CompoundTag oldBlockEntityData = oldState.hasBlockEntity() ? oldBlockEntity.serializeNBT() : null;         if (oldBlockEntity != null) {             pContext.getLevel().removeBlockEntity(blockPos);         }         BlockState FrozenBlock = setFrozenBlock(oldState, oldBlockEntity, oldBlockEntityData);         pContext.getLevel().setBlockAndUpdate(blockPos, FrozenBlock);     }     public static BlockState setFrozenBlock(BlockState blockState, @Nullable BlockEntity blockEntity, @Nullable CompoundTag blockEntityData) {         BlockState FrozenBlock = BlockRegister.FROZEN_BLOCK.get().defaultBlockState();         ((FrozenBlock) FrozenBlock.getBlock()).setOldBlockFields(blockState, blockEntity, blockEntityData);         return FrozenBlock;     }  
  • Topics

×
×
  • Create New...

Important Information

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