Anvil/Chest Manipulation: Difference between revisions

From Minecraft Parkour Wiki
Content added Content deleted
mNo edit summary
m (there -> they)
 
(10 intermediate revisions by 3 users not shown)
Line 1: Line 1:
<languages/>
Anvils don't have a fixed collision box. Instead there is exactly one universal collision box for all variants (North, East, South, West), which is updated whenever the player looks at one. Normal anvils, slightly damaged anvils, and very damaged anvils are not independent.
<translate>
<!--T:1-->
Anvils don't have a fixed collision box. Instead there is a single collision box for all variants (North, East, South, West), which is updated whenever the player looks at one (or by doing other actions which are listed later). Normal anvils, slightly damaged anvils, and very damaged anvils are not independent.


<!--T:2-->
Chests behave in the same way, although only Double Chests have a different collision box. Chests and Trapped Chests are independent.
Chests behave in the same way, though only Double Chests have a different collision box. Chests and Trapped Chests are independent.




<!--T:3-->
By standing next to an anvil/chest, and by looking at another variant, the player can update the collision box in such a way that there are now considered "inside the block". The same trick can be used to artificially extend the length of the anvil/chest, and manage to stand one or two pixels further than intended.
By standing next to an anvil/chest, and by looking at another variant, the player can update the collision box in such a way that they are now considered "inside the block". The same trick can be used to artificially extend the length of the anvil/chest, and manage to stand one or two pixels further than intended.



<!--T:4-->
You must be careful not to look back at the original block, as that will reset the collision box to normal.
You must be careful not to look back at the original block, as that will reset the collision box to normal.





<!--T:5-->
<youtube>https://youtu.be/kiuC71huVdQ</youtube>
<youtube>https://youtu.be/kiuC71huVdQ</youtube>





== Top-view comparison of collision boxes ==
== Top-view comparison of collision boxes == <!--T:6-->

<!--T:7-->
[[File:Anvil-Chest collision box.png|frameless|756x756px]]
[[File:Anvil-Chest collision box.png|frameless|756x756px]]




<!--T:8-->
Anvils are a simple 1×0.75 bounding box (16×12 pixels), that can be oriented along the X or Z axis.
Anvils are a simple 1×0.75 bounding box (16×12 pixels), that can be oriented along the X or Z axis.


<!--T:9-->
Single chests are a simple 0.875×0.875 bounding box (14×14 pixels). The "double chest" variant extends one side by 1 pixel.
Single chests are a simple 0.875×0.875 bounding box (14×14 pixels). The "double chest" variant extends one side by 1 pixel.




<!--T:10-->
In the graphic, darker colors indicate collision areas that are common to all variants : you should stand there in order not to fall during manipulation.
In the graphic, darker colors indicate collision areas that are common to all variants : you should stand there in order not to fall during manipulation.


<!--T:11-->
Lighter colors indicate collision areas that are specific to one variant: the player should stand there in order to clip into the block during manipulation.
Lighter colors indicate collision areas that are specific to one variant: you should stand there in order to clip inside the block during manipulation.






== Explanation ==
The BlockAnvil and BlockChest classes define the setBlockBoundsBasedOnState method as so:<syntaxhighlight lang="java">
/* In BlockAnvil.java */


== Explanation == <!--T:12-->
public void setBlockBoundsBasedOnState(IBlockAccess worldIn, BlockPos pos)

<!--T:13-->
The BlockAnvil and BlockChest classes define the setBlockBoundsBasedOnState method like so:<syntaxhighlight lang="java">
/* Simplified code */

<!--T:14-->
/* In BlockAnvil.java */
public void setBlockBoundsBasedOnState(BlockPos pos)
{
{
EnumFacing enumfacing = (EnumFacing)worldIn.getBlockState(pos).getValue(FACING);
EnumFacing enumfacing = getBlockState(pos).getValue(FACING);


<!--T:15-->
if (enumfacing.getAxis() == EnumFacing.Axis.X)
if (enumfacing.getAxis() == EnumFacing.Axis.X)
{
{
this.setBlockBounds(0.0F, 0.0F, 0.125F, 1.0F, 1.0F, 0.875F);
this.setBlockBounds(0.0, 0.0, 0.125, 1.0, 1.0, 0.875);
}
}
else
else
{
{
this.setBlockBounds(0.125F, 0.0F, 0.0F, 0.875F, 1.0F, 1.0F);
this.setBlockBounds(0.125, 0.0, 0.0, 0.875, 1.0, 1.0);
}
}
}
}




<!--T:16-->
/* In BlockChest.java */
/* In BlockChest.java */
public void setBlockBoundsBasedOnState(IBlockAccess worldIn, BlockPos pos)
public void setBlockBoundsBasedOnState(BlockPos pos)
{
{
if (worldIn.getBlockState(pos.north()).getBlock() == this)
if (getBlockState(pos.north()).getBlock() == this)
{
{
this.setBlockBounds(0.0625F, 0.0F, 0.0F, 0.9375F, 0.875F, 0.9375F);
this.setBlockBounds(0.0625, 0.0, 0.0, 0.9375, 0.875, 0.9375);
}
}
else if (worldIn.getBlockState(pos.south()).getBlock() == this)
else if (getBlockState(pos.south()).getBlock() == this)
{
{
this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.875F, 1.0F);
this.setBlockBounds(0.0625, 0.0, 0.0625, 0.9375, 0.875, 1.0);
}
}
else if (worldIn.getBlockState(pos.west()).getBlock() == this)
else if (getBlockState(pos.west()).getBlock() == this)
{
{
this.setBlockBounds(0.0F, 0.0F, 0.0625F, 0.9375F, 0.875F, 0.9375F);
this.setBlockBounds(0.0, 0.0, 0.0625, 0.9375, 0.875, 0.9375);
}
}
else if (worldIn.getBlockState(pos.east()).getBlock() == this)
else if (getBlockState(pos.east()).getBlock() == this)
{
{
this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 1.0F, 0.875F, 0.9375F);
this.setBlockBounds(0.0625, 0.0, 0.0625, 1.0, 0.875, 0.9375);
}
}
else
else //single chest
{
{
this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.875F, 0.9375F);
this.setBlockBounds(0.0625, 0.0, 0.0625, 0.9375, 0.875, 0.9375);
}
}
}
}
Line 74: Line 97:




<!--T:17-->
This method is called from these other places (same for BlockChest):
This method is called from these other places (same for BlockChest):


<!--T:18-->
[[File:BlockAnvil setBlockBoundsBasedOnState.png|frameless|704x704px]]
[[File:BlockAnvil setBlockBoundsBasedOnState.png|frameless|704x704px]]






<!--T:19-->
Notably, the following actions can be used for manipulation:
Notably, the following actions can be used for manipulation:


<!--T:20-->
* Simply looking at the block (without necessarily drawing its selection box)
* Simply looking at the block (without necessarily drawing its selection box)
* Shooting an arrow at the block (has a persistent effect).
* Shooting an arrow at the block (has a persistent effect).
Line 88: Line 115:




== Limitations ==
On Singleplayer, the player can usually walk through blocks once they clip into one (in this case, the manipulated anvil/chest).


== Limitations == <!--T:21-->
On Multiplayer, the server will typically lagback the player when moving inside a block, unless they are less than 0.0625b away from the edge.

<!--T:22-->
On Singleplayer, the player can usually walk through an anvil or chest once they clip into one.

<!--T:23-->
On Multiplayer, the anticheat will typically prevent the player from walking through an anvil or chest completely.




<!--T:24-->
In 1.9, this mechanic was patched (each variant now has its own collision box).
In 1.9, this mechanic was patched (each variant now has its own collision box).
</translate>

Latest revision as of 09:12, 4 September 2022

Other languages:

Anvils don't have a fixed collision box. Instead there is a single collision box for all variants (North, East, South, West), which is updated whenever the player looks at one (or by doing other actions which are listed later). Normal anvils, slightly damaged anvils, and very damaged anvils are not independent.

Chests behave in the same way, though only Double Chests have a different collision box. Chests and Trapped Chests are independent.


By standing next to an anvil/chest, and by looking at another variant, the player can update the collision box in such a way that they are now considered "inside the block". The same trick can be used to artificially extend the length of the anvil/chest, and manage to stand one or two pixels further than intended.


You must be careful not to look back at the original block, as that will reset the collision box to normal.



Top-view comparison of collision boxes


Anvils are a simple 1×0.75 bounding box (16×12 pixels), that can be oriented along the X or Z axis.

Single chests are a simple 0.875×0.875 bounding box (14×14 pixels). The "double chest" variant extends one side by 1 pixel.


In the graphic, darker colors indicate collision areas that are common to all variants : you should stand there in order not to fall during manipulation.

Lighter colors indicate collision areas that are specific to one variant: you should stand there in order to clip inside the block during manipulation.



Explanation

The BlockAnvil and BlockChest classes define the setBlockBoundsBasedOnState method like so:

/* Simplified code */

/* In BlockAnvil.java */
public void setBlockBoundsBasedOnState(BlockPos pos)
{
    EnumFacing enumfacing = getBlockState(pos).getValue(FACING);

    if (enumfacing.getAxis() == EnumFacing.Axis.X)
    {
        this.setBlockBounds(0.0, 0.0, 0.125, 1.0, 1.0, 0.875);
    }
    else
    {
        this.setBlockBounds(0.125, 0.0, 0.0, 0.875, 1.0, 1.0);
    }
}


/* In BlockChest.java */
public void setBlockBoundsBasedOnState(BlockPos pos)
{
    if (getBlockState(pos.north()).getBlock() == this)
    {
        this.setBlockBounds(0.0625, 0.0, 0.0, 0.9375, 0.875, 0.9375);
    }
    else if (getBlockState(pos.south()).getBlock() == this)
    {
        this.setBlockBounds(0.0625, 0.0, 0.0625, 0.9375, 0.875, 1.0);
    }
    else if (getBlockState(pos.west()).getBlock() == this)
    {
        this.setBlockBounds(0.0, 0.0, 0.0625, 0.9375, 0.875, 0.9375);
    }
    else if (getBlockState(pos.east()).getBlock() == this)
    {
        this.setBlockBounds(0.0625, 0.0, 0.0625, 1.0, 0.875, 0.9375);
    }
    else //single chest
    {
        this.setBlockBounds(0.0625, 0.0, 0.0625, 0.9375, 0.875, 0.9375);
    }
}


This method is called from these other places (same for BlockChest):


Notably, the following actions can be used for manipulation:

  • Simply looking at the block (without necessarily drawing its selection box)
  • Shooting an arrow at the block (has a persistent effect).
  • Causing the block to re-render, which can be done by updating the surroundings.
  • Using rain to update the block (randomly).


Limitations

On Singleplayer, the player can usually walk through an anvil or chest once they clip into one.

On Multiplayer, the anticheat will typically prevent the player from walking through an anvil or chest completely.


In 1.9, this mechanic was patched (each variant now has its own collision box).