# Water and Lava

Other languages:

[WIP]

## Basics

When moving in water or lava, the game doesn't consider whether the player is on ground or not, only if they are holding space.

When exiting a liquid -> jump boost with 0.3 initial speed

Water collision: 0.998 x 0.598 x 0.998 (1x0.6x1 retracted 0.001 inwards)

Lava collision: 0.8 x 0.6 x 0.8 (1x0.6x1 retracted 0.1 inward except for Y)

## Water

When pressing jump: threshold(motY*0.8 - 0.02) + 0.04

Otherwise: threshold(motY*0.8 - 0.02)

The threshold is actually important, because the player's motY would be -0.004 after the first tick of moving.

In 1.8, the player's speed on the second tick is 0.04,

TODO: X/Z motion

## Lava

When pressing jump: threshold(motY*0.5 - 0.02) + 0.04

Otherwise: threshold(motY*0.5 - 0.02)

TODO: X/Z motion

## Code

Flowing water:
```/* From Entity.java */
public boolean handleWaterMovement()
{
if (world.handleWater(this.getEntityBoundingBox().contract(0.001, 0.401, 0.001), Material.water, this))
{
this.fallDistance = 0.0F;
this.inWater = true;
this.fire = 0;
}

else
{
this.inWater = false;
}

return this.inWater;
}

/* From World.java */
public boolean handleWater(AxisAlignedBB bb, Material materialIn, Entity entityIn)
{
int minX = MathHelper.floor_double(bb.minX);
int maxX = MathHelper.floor_double(bb.maxX + 1.0D);
int minY = MathHelper.floor_double(bb.minY);
int maxY = MathHelper.floor_double(bb.maxY + 1.0D);
int minZ = MathHelper.floor_double(bb.minZ);
int maxZ = MathHelper.floor_double(bb.maxZ + 1.0D);

{
boolean inWater = false;
Vec3 acceleration = new Vec3(0.0D, 0.0D, 0.0D);
BlockPos.MutableBlockPos blockpos = new BlockPos.MutableBlockPos();

for (int x = minX; x < maxX; ++x)
{
for (int y = minY; y < maxY; ++y)
{
for (int z = minZ; z < maxZ; ++z)
{
blockpos.mutate(x, y, z);
IBlockState iblockstate = this.getBlockState(blockpos);
Block block = iblockstate.getBlock();

if (block.getMaterial() == materialIn)
{
double level = y + 1 -BlockLiquid.getLiquidHeightPercent(iblockstate.getValue(BlockLiquid.LEVEL));
//liquidHeightPercent(i) returns (i + 1) / 9.0F;

if (maxY >= level)
{
inWater = true;
acceleration = block.modifyAcceleration(this, blockpos, entityIn, acceleration);
}
}
}
}
}

if (acceleration.lengthVector() > 0.0D && entityIn.isPushedByWater())
{
acceleration = acceleration.normalize();
double mult = 0.014D;
entityIn.motionX += acceleration.xCoord * mult;
entityIn.motionY += acceleration.yCoord * mult;
entityIn.motionZ += acceleration.zCoord * mult;
}

return inWater;
}
}

/* From BlockLiquid.java */
public Vec3 modifyAcceleration(World worldIn, BlockPos pos, Entity entityIn, Vec3 motion)
{