Jump to content

[1.8][SOLVED] Need help with changing blockmodel (via blockstate)from tileentity


Kant0sh

Recommended Posts

I'm working on a block that faces a direction and has five levels of water... so i can't store all that in a byte of meta. I just tried to save the water level in NBT, which worked, then I changed the shouldRefresh() to return false and added a statement to remove the TE in it's update method. After I started debugging, I saw that, no matter what is saved in NBT, the water level will always be set to 4 (the max) and even when i hardcoded the TE to set the value of the water level in the blockstate to 0, it was still debugged as 4 one line later! I have no idea.... any help is greatly appreciated!

 

Source (GitHub):

 

https://github.com/Kant0sh/MD/blob/master/src/main/java/com/kant0sh/md/tileEntities/BigCauldronTileEntity.java --> TileEntity class

 

https://github.com/Kant0sh/MD/blob/master/src/main/java/com/kant0sh/md/blocks/BigCauldronBlock.java --> Block class

 

https://github.com/Kant0sh/MD/blob/master/src/main/resources/assets/md/blockstates/bigCauldron.json --> Blockstates .json

 

Quick Source!

 

Essential parts of TE class:

 

if(!(worldObj.getBlockState(pos).getBlock() instanceof BigCauldronBlock)){

worldObj.setTileEntity(pos, null);

return;

}

 

worldObj.setBlockState(pos, worldObj.getBlockState(pos).withProperty(((BigCauldronBlock) worldObj.getBlockState(pos).getBlock()).LEVEL, this.getWaterLevel()));

worldObj.scheduleUpdate(pos, worldObj.getBlockState(pos).getBlock(), 0);

 

@Override

public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newSate) {

return false;

}

 

// NBT read and write

 

public int getWaterLevel() {

return waterLevel;

}

 

public void setWaterLevel(int waterLevel) {

this.waterLevel = waterLevel;

}

 

public int getMaxWaterLevel() {

return 4;

}

 

Essential parts of Block class:

 

public static final PropertyDirection FACING = PropertyDirection.create("facing", EnumFacing.Plane.HORIZONTAL);

public static final PropertyInteger LEVEL = PropertyInteger.create("level", 0, 4);

 

public BigCauldronBlock() {

super("bigCauldron");

setDefaultState(this.blockState.getBaseState().withProperty(FACING, EnumFacing.NORTH).withProperty(LEVEL, 0));

}

 

@Override

public IBlockState getStateForEntityRender(IBlockState state) {

return this.getDefaultState().withProperty(FACING, EnumFacing.SOUTH).withProperty(LEVEL, 0);

}

 

@Override

public IBlockState getStateFromMeta(int meta) {

 

EnumFacing enumFacing = EnumFacing.getFront(meta);

 

if(enumFacing.getAxis() == EnumFacing.Axis.Y){

enumFacing = enumFacing.NORTH;

}

 

return this.getDefaultState().withProperty(FACING, enumFacing);

}

 

@Override

public int getMetaFromState(IBlockState state) {

return ((EnumFacing) state.getValue(FACING)).getIndex();

}

 

@Override

protected BlockState createBlockState() {

return new BlockState(this, new IProperty[]{FACING, LEVEL});

}

 

@Override

public TileEntity createTileEntity(World world, IBlockState state) {

return new BigCauldronTileEntity();

}

 

@Override

public IBlockState onBlockPlaced(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) {

return this.getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite());

}

 

Blockstate .json:

 

{

   

    "variants": {

   

        "facing=north,level=0": { "model": "md:bigCauldronEmpty" },

        "facing=north,level=1": { "model": "md:bigCauldronLevel1" },

        "facing=north,level=2": { "model": "md:bigCauldronLevel2" },

        "facing=north,level=3": { "model": "md:bigCauldronLevel3" },

        "facing=north,level=4": { "model": "md:bigCauldronLevel4" },

       

        "facing=south,level=0": { "model": "md:bigCauldronEmpty", "y": 180 },

        "facing=south,level=1": { "model": "md:bigCauldronLevel1", "y": 180 },

        "facing=south,level=2": { "model": "md:bigCauldronLevel2", "y": 180 },

        "facing=south,level=3": { "model": "md:bigCauldronLevel3", "y": 180 },

        "facing=south,level=4": { "model": "md:bigCauldronLevel4", "y": 180 },

       

        "facing=west,level=0": { "model": "md:bigCauldronEmpty", "y": 270 },

        "facing=west,level=1": { "model": "md:bigCauldronLevel1", "y": 270 },

        "facing=west,level=2": { "model": "md:bigCauldronLevel2", "y": 270 },

        "facing=west,level=3": { "model": "md:bigCauldronLevel3", "y": 270 },

        "facing=west,level=4": { "model": "md:bigCauldronLevel4", "y": 270 },

       

        "facing=east,level=0": { "model": "md:bigCauldronEmpty", "y": 90 },

        "facing=east,level=1": { "model": "md:bigCauldronLevel1", "y": 90 },

        "facing=east,level=2": { "model": "md:bigCauldronLevel2", "y": 90 },

        "facing=east,level=3": { "model": "md:bigCauldronLevel3", "y": 90 },

        "facing=east,level=4": { "model": "md:bigCauldronLevel4", "y": 90 }

       

    }

   

}

Thanks for helping me <3

Link to comment
Share on other sites

I tried to apply it via the TileEntity with the first "Oh god why"... but even if I'm not applying anything, why would it always jump to 4? I edited the write to NBT to seve 0, and after reloading the world it still was immediately changed to 4

 

PS: btw most of the stuff you mentioned is left over from code i tampered with previously and just trial and error.... i left in what worked :D

Thanks for helping me <3

Link to comment
Share on other sites

I need help with one more thing... the blockstate now changes to the correct values and responds correctly, but the model that's rendered doesn't change. Do i have to call some kind of update manually?

Thanks for helping me <3

Link to comment
Share on other sites

I now have the correct state over in my Block class in the client side of the onBlockActivated! but how do i get it to update from there? just setting the state variable doesn't work and the blockState field is final :/

Thanks for helping me <3

Link to comment
Share on other sites

public void setWaterLevel(int waterLevel) {

this.waterLevel = waterLevel;

}

 

I created this setter alongside with a field in the Block class. I call this function in the Runnable in onMessage, as you described in your tutorial. Now i have a section in the onBlockActivated() method where world.isRemote is true and was trying to set the blockState of the class appropriately there. is there a method to do so or how do i tell the renderengine to render another model?

 

state = (IBlockState) getDefaultState().withProperty(FACING, state.getValue(FACING)).withProperty(LEVEL, waterLevel);

 

that is my try to use a field already in the minecraft.block.Block class.

Thanks for helping me <3

Link to comment
Share on other sites

I'm honestly sorry for bothering you for so long but i can't seem to get anywhere... I have used the getActualState method to get the data from the TE to my block, then i've sent the packet with basically the same data to the client (or as the method is called, sendToAll) and now i have  gotten the data basically everywhere i could possibly work with it. Still, i don't know how to effectively "change" or "update" my BlockState so that it tells minecraft to use the correct variant specified in the blockstate json....  what ive seen by googling just said use packets and then it works, but I'm missing an essential piece of code here :|

Thanks for helping me <3

Link to comment
Share on other sites

Rendering works fine, but needs a block update... which i cant figure out how to do because even after a few ticks of delay, the metchods google brought up dont work. also, when i break the block the TE is removed and everything is as usual, but when i replace a Cauldron in the exact same spot, its waterLevel is back...? even if there was another block there (wll air is going to be there anyway). And if i place a chest there, it does not render and the waterLevel is still maintained. I will push again if you want to have another look

Thanks for helping me <3

Link to comment
Share on other sites

1. I want to render a changing water level in the cauldron upon filling it with buckets. After right clicking it with a bucket, the cauldron needs a manual blockupdate, and i dont know how to do that in the code.

 

2. After breaking the cauldron block, it removes the block and its tileentity from the world like usual, but as soon as i place a cauldron back in the same spot, it gets the water back, the previous one had in it.

 

3. when placing a chest in the spot where a filled cauldron was, the chest does not render at all, but behaves normally. still, the water level is somehow retained when removing the chest and placing a cauldron back... weird, is it not?

 

might put up some screenshots if i get good ones

Thanks for helping me <3

Link to comment
Share on other sites

2. & 3.: so in shouldRefresh i check if the block is still there and if not return true? i thought that

 

if(!(worldObj.getBlockState(pos).getBlock() instanceof BigCauldronBlock)){

worldObj.setTileEntity(pos, null);

return;

}

 

would do it... derp :P

 

1. do you mean in onMessage? because in the TE update (the place that calls after changing the waterlevel) i did that already even with a few ticks delay...

Thanks for helping me <3

Link to comment
Share on other sites

I have this:

 

@Override

public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newSate) {

return oldState.getBlock() != newSate.getBlock();

}

 

i removed the crap...

 

this:

 

Minecraft.getMinecraft().theWorld.markBlockForUpdate(new BlockPos(message.x, message.y, message.z));

 

in the onMessage run method

 

AND EVERYTHING WORKS!!!!!!! Thanks sooo much man!

Thanks for helping me <3

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.