aboutsummaryrefslogtreecommitdiffhomepage
path: root/patch-remap/mache-vineflower/net/minecraft/world/entity/vehicle/Boat.java.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patch-remap/mache-vineflower/net/minecraft/world/entity/vehicle/Boat.java.patch')
-rw-r--r--patch-remap/mache-vineflower/net/minecraft/world/entity/vehicle/Boat.java.patch1156
1 files changed, 1156 insertions, 0 deletions
diff --git a/patch-remap/mache-vineflower/net/minecraft/world/entity/vehicle/Boat.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/entity/vehicle/Boat.java.patch
new file mode 100644
index 0000000000..4efaffd9de
--- /dev/null
+++ b/patch-remap/mache-vineflower/net/minecraft/world/entity/vehicle/Boat.java.patch
@@ -0,0 +1,1156 @@
+--- a/net/minecraft/world/entity/vehicle/Boat.java
++++ b/net/minecraft/world/entity/vehicle/Boat.java
+@@ -1,6 +1,8 @@
+ package net.minecraft.world.entity.vehicle;
+
+ import com.google.common.collect.Lists;
++import com.google.common.collect.UnmodifiableIterator;
++import java.util.Iterator;
+ import java.util.List;
+ import java.util.function.IntFunction;
+ import javax.annotation.Nullable;
+@@ -21,15 +23,15 @@
+ import net.minecraft.util.ByIdMap;
+ import net.minecraft.util.Mth;
+ import net.minecraft.util.StringRepresentable;
+-import net.minecraft.world.InteractionHand;
++import net.minecraft.world.EnumHand;
+ import net.minecraft.world.InteractionResult;
+ import net.minecraft.world.entity.Entity;
+ import net.minecraft.world.entity.EntityDimensions;
++import net.minecraft.world.entity.EntityPose;
+ import net.minecraft.world.entity.EntitySelector;
+ import net.minecraft.world.entity.EntityType;
++import net.minecraft.world.entity.EnumMoveType;
+ import net.minecraft.world.entity.LivingEntity;
+-import net.minecraft.world.entity.MoverType;
+-import net.minecraft.world.entity.Pose;
+ import net.minecraft.world.entity.VariantHolder;
+ import net.minecraft.world.entity.animal.Animal;
+ import net.minecraft.world.entity.animal.WaterAnimal;
+@@ -38,11 +40,12 @@
+ import net.minecraft.world.item.ItemStack;
+ import net.minecraft.world.item.Items;
+ import net.minecraft.world.level.GameRules;
++import net.minecraft.world.level.IMaterial;
+ import net.minecraft.world.level.Level;
+ import net.minecraft.world.level.block.Block;
+ import net.minecraft.world.level.block.Blocks;
+ import net.minecraft.world.level.block.WaterlilyBlock;
+-import net.minecraft.world.level.block.state.BlockState;
++import net.minecraft.world.level.block.state.IBlockData;
+ import net.minecraft.world.level.gameevent.GameEvent;
+ import net.minecraft.world.level.material.FluidState;
+ import net.minecraft.world.phys.AABB;
+@@ -52,7 +55,17 @@
+ import net.minecraft.world.phys.shapes.VoxelShape;
+ import org.joml.Vector3f;
+
++// CraftBukkit start
++import org.bukkit.Location;
++import org.bukkit.craftbukkit.util.CraftLocation;
++import org.bukkit.entity.Vehicle;
++import org.bukkit.event.vehicle.VehicleDestroyEvent;
++import org.bukkit.event.vehicle.VehicleEntityCollisionEvent;
++import org.bukkit.event.vehicle.VehicleMoveEvent;
++// CraftBukkit end
++
+ public class Boat extends VehicleEntity implements VariantHolder<Boat.Type> {
++
+ private static final EntityDataAccessor<Integer> DATA_ID_TYPE = SynchedEntityData.defineId(Boat.class, EntityDataSerializers.INT);
+ private static final EntityDataAccessor<Boolean> DATA_ID_PADDLE_LEFT = SynchedEntityData.defineId(Boat.class, EntityDataSerializers.BOOLEAN);
+ private static final EntityDataAccessor<Boolean> DATA_ID_PADDLE_RIGHT = SynchedEntityData.defineId(Boat.class, EntityDataSerializers.BOOLEAN);
+@@ -60,10 +73,10 @@
+ public static final int PADDLE_LEFT = 0;
+ public static final int PADDLE_RIGHT = 1;
+ private static final int TIME_TO_EJECT = 60;
+- private static final float PADDLE_SPEED = (float) (Math.PI / 8);
+- public static final double PADDLE_SOUND_TIME = (float) (Math.PI / 4);
++ private static final float PADDLE_SPEED = 0.3926991F;
++ public static final double PADDLE_SOUND_TIME = 0.7853981852531433D;
+ public static final int BUBBLE_TIME = 60;
+- private final float[] paddlePositions = new float[2];
++ private final float[] paddlePositions;
+ private float invFriction;
+ private float outOfControlTicks;
+ private float deltaRotation;
+@@ -79,8 +92,8 @@
+ private boolean inputDown;
+ private double waterLevel;
+ private float landFriction;
+- private Boat.Status status;
+- private Boat.Status oldStatus;
++ public Boat.EnumStatus status;
++ private Boat.EnumStatus oldStatus;
+ private double lastYd;
+ private boolean isAboveBubbleColumn;
+ private boolean bubbleColumnDirectionIsDown;
+@@ -88,21 +101,30 @@
+ private float bubbleAngle;
+ private float bubbleAngleO;
+
++ // CraftBukkit start
++ // PAIL: Some of these haven't worked since a few updates, and since 1.9 they are less and less applicable.
++ public double maxSpeed = 0.4D;
++ public double occupiedDeceleration = 0.2D;
++ public double unoccupiedDeceleration = -1;
++ public boolean landBoats = false;
++ // CraftBukkit end
++
+ public Boat(EntityType<? extends Boat> entityType, Level level) {
+ super(entityType, level);
++ this.paddlePositions = new float[2];
+ this.blocksBuilding = true;
+ }
+
+- public Boat(Level level, double x, double y, double z) {
++ public Boat(Level level, double x, double d1, double y) {
+ this(EntityType.BOAT, level);
+- this.setPos(x, y, z);
++ this.setPos(x, d1, y);
+ this.xo = x;
+- this.yo = y;
+- this.zo = z;
++ this.yo = d1;
++ this.zo = y;
+ }
+
+ @Override
+- protected float getEyeHeight(Pose pose, EntityDimensions size) {
++ protected float getEyeHeight(EntityPose pose, EntityDimensions size) {
+ return size.height;
+ }
+
+@@ -114,10 +136,10 @@
+ @Override
+ protected void defineSynchedData() {
+ super.defineSynchedData();
+- this.entityData.define(DATA_ID_TYPE, Boat.Type.OAK.ordinal());
+- this.entityData.define(DATA_ID_PADDLE_LEFT, false);
+- this.entityData.define(DATA_ID_PADDLE_RIGHT, false);
+- this.entityData.define(DATA_ID_BUBBLE_TIME, 0);
++ this.entityData.define(Boat.DATA_ID_TYPE, Boat.Type.OAK.ordinal());
++ this.entityData.define(Boat.DATA_ID_PADDLE_LEFT, false);
++ this.entityData.define(Boat.DATA_ID_PADDLE_RIGHT, false);
++ this.entityData.define(Boat.DATA_ID_BUBBLE_TIME, 0);
+ }
+
+ @Override
+@@ -145,24 +167,24 @@
+ }
+
+ @Override
+- protected Vector3f getPassengerAttachmentPoint(Entity entity, EntityDimensions entityDimensions, float f) {
+- float singlePassengerXOffset = this.getSinglePassengerXOffset();
++ protected Vector3f getPassengerAttachmentPoint(Entity entity, EntityDimensions entitysize, float f) {
++ float f1 = this.getSinglePassengerXOffset();
++
+ if (this.getPassengers().size() > 1) {
+- int index = this.getPassengers().indexOf(entity);
+- if (index == 0) {
+- singlePassengerXOffset = 0.2F;
++ int i = this.getPassengers().indexOf(entity);
++
++ if (i == 0) {
++ f1 = 0.2F;
+ } else {
+- singlePassengerXOffset = -0.6F;
++ f1 = -0.6F;
+ }
+
+ if (entity instanceof Animal) {
+- singlePassengerXOffset += 0.2F;
++ f1 += 0.2F;
+ }
+ }
+
+- return new Vector3f(
+- 0.0F, this.getVariant() == Boat.Type.BAMBOO ? entityDimensions.height * 0.8888889F : entityDimensions.height / 3.0F, singlePassengerXOffset
+- );
++ return new Vector3f(0.0F, this.getVariant() == Boat.Type.BAMBOO ? entitysize.height * 0.8888889F : entitysize.height / 3.0F, f1);
+ }
+
+ @Override
+@@ -175,49 +197,80 @@
+ }
+ }
+
+- this.level()
+- .addParticle(
+- ParticleTypes.SPLASH,
+- this.getX() + (double)this.random.nextFloat(),
+- this.getY() + 0.7,
+- this.getZ() + (double)this.random.nextFloat(),
+- 0.0,
+- 0.0,
+- 0.0
+- );
++ this.level().addParticle(ParticleTypes.SPLASH, this.getX() + (double) this.random.nextFloat(), this.getY() + 0.7D, this.getZ() + (double) this.random.nextFloat(), 0.0D, 0.0D, 0.0D);
+ if (this.random.nextInt(20) == 0) {
+- this.level()
+- .playLocalSound(
+- this.getX(), this.getY(), this.getZ(), this.getSwimSplashSound(), this.getSoundSource(), 1.0F, 0.8F + 0.4F * this.random.nextFloat(), false
+- );
++ this.level().playLocalSound(this.getX(), this.getY(), this.getZ(), this.getSwimSplashSound(), this.getSoundSource(), 1.0F, 0.8F + 0.4F * this.random.nextFloat(), false);
+ this.gameEvent(GameEvent.SPLASH, this.getControllingPassenger());
+ }
++
+ }
+
+ @Override
+ public void push(Entity entity) {
+ if (entity instanceof Boat) {
+ if (entity.getBoundingBox().minY < this.getBoundingBox().maxY) {
++ // CraftBukkit start
++ if (!this.isPassengerOfSameVehicle(entity)) {
++ VehicleEntityCollisionEvent event = new VehicleEntityCollisionEvent((Vehicle) this.getBukkitEntity(), entity.getBukkitEntity());
++ this.level().getCraftServer().getPluginManager().callEvent(event);
++
++ if (event.isCancelled()) {
++ return;
++ }
++ }
++ // CraftBukkit end
+ super.push(entity);
+ }
+ } else if (entity.getBoundingBox().minY <= this.getBoundingBox().minY) {
++ // CraftBukkit start
++ if (!this.isPassengerOfSameVehicle(entity)) {
++ VehicleEntityCollisionEvent event = new VehicleEntityCollisionEvent((Vehicle) this.getBukkitEntity(), entity.getBukkitEntity());
++ this.level().getCraftServer().getPluginManager().callEvent(event);
++
++ if (event.isCancelled()) {
++ return;
++ }
++ }
++ // CraftBukkit end
+ super.push(entity);
+ }
++
+ }
+
+ @Override
+ public Item getDropItem() {
+- return switch (this.getVariant()) {
+- case SPRUCE -> Items.SPRUCE_BOAT;
+- case BIRCH -> Items.BIRCH_BOAT;
+- case JUNGLE -> Items.JUNGLE_BOAT;
+- case ACACIA -> Items.ACACIA_BOAT;
+- case CHERRY -> Items.CHERRY_BOAT;
+- case DARK_OAK -> Items.DARK_OAK_BOAT;
+- case MANGROVE -> Items.MANGROVE_BOAT;
+- case BAMBOO -> Items.BAMBOO_RAFT;
+- default -> Items.OAK_BOAT;
+- };
++ Item item;
++
++ switch (this.getVariant()) {
++ case SPRUCE:
++ item = Items.SPRUCE_BOAT;
++ break;
++ case BIRCH:
++ item = Items.BIRCH_BOAT;
++ break;
++ case JUNGLE:
++ item = Items.JUNGLE_BOAT;
++ break;
++ case ACACIA:
++ item = Items.ACACIA_BOAT;
++ break;
++ case CHERRY:
++ item = Items.CHERRY_BOAT;
++ break;
++ case DARK_OAK:
++ item = Items.DARK_OAK_BOAT;
++ break;
++ case MANGROVE:
++ item = Items.MANGROVE_BOAT;
++ break;
++ case BAMBOO:
++ item = Items.BAMBOO_RAFT;
++ break;
++ default:
++ item = Items.OAK_BOAT;
++ }
++
++ return item;
+ }
+
+ @Override
+@@ -233,12 +286,12 @@
+ }
+
+ @Override
+- public void lerpTo(double d, double d1, double d2, float f, float f1, int i) {
+- this.lerpX = d;
++ public void lerpTo(double d0, double d1, double d2, float f, float f1, int i) {
++ this.lerpX = d0;
+ this.lerpY = d1;
+ this.lerpZ = d2;
+- this.lerpYRot = (double)f;
+- this.lerpXRot = (double)f1;
++ this.lerpYRot = (double) f;
++ this.lerpXRot = (double) f1;
+ this.lerpSteps = 10;
+ }
+
+@@ -259,12 +312,12 @@
+
+ @Override
+ public float lerpTargetXRot() {
+- return this.lerpSteps > 0 ? (float)this.lerpXRot : this.getXRot();
++ return this.lerpSteps > 0 ? (float) this.lerpXRot : this.getXRot();
+ }
+
+ @Override
+ public float lerpTargetYRot() {
+- return this.lerpSteps > 0 ? (float)this.lerpYRot : this.getYRot();
++ return this.lerpSteps > 0 ? (float) this.lerpYRot : this.getYRot();
+ }
+
+ @Override
+@@ -272,14 +325,15 @@
+ return this.getDirection().getClockWise();
+ }
+
++ private Location lastLocation; // CraftBukkit
+ @Override
+ public void tick() {
+ this.oldStatus = this.status;
+ this.status = this.getStatus();
+- if (this.status != Boat.Status.UNDER_WATER && this.status != Boat.Status.UNDER_FLOWING_WATER) {
++ if (this.status != Boat.EnumStatus.UNDER_WATER && this.status != Boat.EnumStatus.UNDER_FLOWING_WATER) {
+ this.outOfControlTicks = 0.0F;
+ } else {
+- this.outOfControlTicks++;
++ ++this.outOfControlTicks;
+ }
+
+ if (!this.level().isClientSide && this.outOfControlTicks >= 60.0F) {
+@@ -307,57 +361,61 @@
+ this.level().sendPacketToServer(new ServerboundPaddleBoatPacket(this.getPaddleState(0), this.getPaddleState(1)));
+ }
+
+- this.move(MoverType.SELF, this.getDeltaMovement());
++ this.move(EnumMoveType.SELF, this.getDeltaMovement());
+ } else {
+ this.setDeltaMovement(Vec3.ZERO);
+ }
+
++ // CraftBukkit start
++ org.bukkit.Server server = this.level().getCraftServer();
++ org.bukkit.World bworld = this.level().getWorld();
++
++ Location to = CraftLocation.toBukkit(this.position(), bworld, this.getYRot(), this.getXRot());
++ Vehicle vehicle = (Vehicle) this.getBukkitEntity();
++
++ server.getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleUpdateEvent(vehicle));
++
++ if (lastLocation != null && !lastLocation.equals(to)) {
++ VehicleMoveEvent event = new VehicleMoveEvent(vehicle, lastLocation, to);
++ server.getPluginManager().callEvent(event);
++ }
++ lastLocation = vehicle.getLocation();
++ // CraftBukkit end
++
+ this.tickBubbleColumn();
+
+- for (int i = 0; i <= 1; i++) {
++ for (int i = 0; i <= 1; ++i) {
+ if (this.getPaddleState(i)) {
+- if (!this.isSilent()
+- && (double)(this.paddlePositions[i] % (float) (Math.PI * 2)) <= (float) (Math.PI / 4)
+- && (double)((this.paddlePositions[i] + (float) (Math.PI / 8)) % (float) (Math.PI * 2)) >= (float) (Math.PI / 4)) {
+- SoundEvent paddleSound = this.getPaddleSound();
+- if (paddleSound != null) {
+- Vec3 viewVector = this.getViewVector(1.0F);
+- double d = i == 1 ? -viewVector.z : viewVector.z;
+- double d1 = i == 1 ? viewVector.x : -viewVector.x;
+- this.level()
+- .playSound(
+- null,
+- this.getX() + d,
+- this.getY(),
+- this.getZ() + d1,
+- paddleSound,
+- this.getSoundSource(),
+- 1.0F,
+- 0.8F + 0.4F * this.random.nextFloat()
+- );
++ if (!this.isSilent() && (double) (this.paddlePositions[i] % 6.2831855F) <= 0.7853981852531433D && (double) ((this.paddlePositions[i] + 0.3926991F) % 6.2831855F) >= 0.7853981852531433D) {
++ SoundEvent soundeffect = this.getPaddleSound();
++
++ if (soundeffect != null) {
++ Vec3 vec3d = this.getViewVector(1.0F);
++ double d0 = i == 1 ? -vec3d.z : vec3d.z;
++ double d1 = i == 1 ? vec3d.x : -vec3d.x;
++
++ this.level().playSound((Player) null, this.getX() + d0, this.getY(), this.getZ() + d1, soundeffect, this.getSoundSource(), 1.0F, 0.8F + 0.4F * this.random.nextFloat());
+ }
+ }
+
+- this.paddlePositions[i] = this.paddlePositions[i] + (float) (Math.PI / 8);
++ this.paddlePositions[i] += 0.3926991F;
+ } else {
+ this.paddlePositions[i] = 0.0F;
+ }
+ }
+
+ this.checkInsideBlocks();
+- List<Entity> entities = this.level().getEntities(this, this.getBoundingBox().inflate(0.2F, -0.01F, 0.2F), EntitySelector.pushableBy(this));
+- if (!entities.isEmpty()) {
++ List<Entity> list = this.level().getEntities((Entity) this, this.getBoundingBox().inflate(0.20000000298023224D, -0.009999999776482582D, 0.20000000298023224D), EntitySelector.pushableBy(this));
++
++ if (!list.isEmpty()) {
+ boolean flag = !this.level().isClientSide && !(this.getControllingPassenger() instanceof Player);
++ Iterator iterator = list.iterator();
+
+- for (Entity entity : entities) {
+- if (!entity.hasPassenger(this)) {
+- if (flag
+- && this.getPassengers().size() < this.getMaxPassengers()
+- && !entity.isPassenger()
+- && this.hasEnoughSpaceFor(entity)
+- && entity instanceof LivingEntity
+- && !(entity instanceof WaterAnimal)
+- && !(entity instanceof Player)) {
++ while (iterator.hasNext()) {
++ Entity entity = (Entity) iterator.next();
++
++ if (!entity.hasPassenger((Entity) this)) {
++ if (flag && this.getPassengers().size() < this.getMaxPassengers() && !entity.isPassenger() && this.hasEnoughSpaceFor(entity) && entity instanceof LivingEntity && !(entity instanceof WaterAnimal) && !(entity instanceof Player)) {
+ entity.startRiding(this);
+ } else {
+ this.push(entity);
+@@ -365,12 +423,15 @@
+ }
+ }
+ }
++
+ }
+
+ private void tickBubbleColumn() {
++ int i;
++
+ if (this.level().isClientSide) {
+- int bubbleTime = this.getBubbleTime();
+- if (bubbleTime > 0) {
++ i = this.getBubbleTime();
++ if (i > 0) {
+ this.bubbleMultiplier += 0.05F;
+ } else {
+ this.bubbleMultiplier -= 0.1F;
+@@ -378,30 +439,36 @@
+
+ this.bubbleMultiplier = Mth.clamp(this.bubbleMultiplier, 0.0F, 1.0F);
+ this.bubbleAngleO = this.bubbleAngle;
+- this.bubbleAngle = 10.0F * (float)Math.sin((double)(0.5F * (float)this.level().getGameTime())) * this.bubbleMultiplier;
++ this.bubbleAngle = 10.0F * (float) Math.sin((double) (0.5F * (float) this.level().getGameTime())) * this.bubbleMultiplier;
+ } else {
+ if (!this.isAboveBubbleColumn) {
+ this.setBubbleTime(0);
+ }
+
+- int bubbleTime = this.getBubbleTime();
+- if (bubbleTime > 0) {
+- this.setBubbleTime(--bubbleTime);
+- int i = 60 - bubbleTime - 1;
+- if (i > 0 && bubbleTime == 0) {
++ i = this.getBubbleTime();
++ if (i > 0) {
++ --i;
++ this.setBubbleTime(i);
++ int j = 60 - i - 1;
++
++ if (j > 0 && i == 0) {
+ this.setBubbleTime(0);
+- Vec3 deltaMovement = this.getDeltaMovement();
++ Vec3 vec3d = this.getDeltaMovement();
++
+ if (this.bubbleColumnDirectionIsDown) {
+- this.setDeltaMovement(deltaMovement.add(0.0, -0.7, 0.0));
++ this.setDeltaMovement(vec3d.add(0.0D, -0.7D, 0.0D));
+ this.ejectPassengers();
+ } else {
+- this.setDeltaMovement(deltaMovement.x, this.hasPassenger(entity -> entity instanceof Player) ? 2.7 : 0.6, deltaMovement.z);
++ this.setDeltaMovement(vec3d.x, this.hasPassenger((entity) -> {
++ return entity instanceof Player;
++ }) ? 2.7D : 0.6D, vec3d.z);
+ }
+ }
+
+ this.isAboveBubbleColumn = false;
+ }
+ }
++
+ }
+
+ @Nullable
+@@ -427,103 +494,117 @@
+
+ if (this.lerpSteps > 0) {
+ this.lerpPositionAndRotationStep(this.lerpSteps, this.lerpX, this.lerpY, this.lerpZ, this.lerpYRot, this.lerpXRot);
+- this.lerpSteps--;
++ --this.lerpSteps;
+ }
+ }
+
+ public void setPaddleState(boolean left, boolean right) {
+- this.entityData.set(DATA_ID_PADDLE_LEFT, left);
+- this.entityData.set(DATA_ID_PADDLE_RIGHT, right);
++ this.entityData.set(Boat.DATA_ID_PADDLE_LEFT, left);
++ this.entityData.set(Boat.DATA_ID_PADDLE_RIGHT, right);
+ }
+
+ public float getRowingTime(int side, float limbSwing) {
+- return this.getPaddleState(side) ? Mth.clampedLerp(this.paddlePositions[side] - (float) (Math.PI / 8), this.paddlePositions[side], limbSwing) : 0.0F;
++ return this.getPaddleState(side) ? Mth.clampedLerp(this.paddlePositions[side] - 0.3926991F, this.paddlePositions[side], limbSwing) : 0.0F;
+ }
+
+- private Boat.Status getStatus() {
+- Boat.Status status = this.isUnderwater();
+- if (status != null) {
++ private Boat.EnumStatus getStatus() {
++ Boat.EnumStatus entityboat_enumstatus = this.isUnderwater();
++
++ if (entityboat_enumstatus != null) {
+ this.waterLevel = this.getBoundingBox().maxY;
+- return status;
++ return entityboat_enumstatus;
+ } else if (this.checkInWater()) {
+- return Boat.Status.IN_WATER;
++ return Boat.EnumStatus.IN_WATER;
+ } else {
+- float groundFriction = this.getGroundFriction();
+- if (groundFriction > 0.0F) {
+- this.landFriction = groundFriction;
+- return Boat.Status.ON_LAND;
++ float f = this.getGroundFriction();
++
++ if (f > 0.0F) {
++ this.landFriction = f;
++ return Boat.EnumStatus.ON_LAND;
+ } else {
+- return Boat.Status.IN_AIR;
++ return Boat.EnumStatus.IN_AIR;
+ }
+ }
+ }
+
+ public float getWaterLevelAbove() {
+- AABB boundingBox = this.getBoundingBox();
+- int floor = Mth.floor(boundingBox.minX);
+- int ceil = Mth.ceil(boundingBox.maxX);
+- int floor1 = Mth.floor(boundingBox.maxY);
+- int ceil1 = Mth.ceil(boundingBox.maxY - this.lastYd);
+- int floor2 = Mth.floor(boundingBox.minZ);
+- int ceil2 = Mth.ceil(boundingBox.maxZ);
+- BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
++ AABB axisalignedbb = this.getBoundingBox();
++ int i = Mth.floor(axisalignedbb.minX);
++ int j = Mth.ceil(axisalignedbb.maxX);
++ int k = Mth.floor(axisalignedbb.maxY);
++ int l = Mth.ceil(axisalignedbb.maxY - this.lastYd);
++ int i1 = Mth.floor(axisalignedbb.minZ);
++ int j1 = Mth.ceil(axisalignedbb.maxZ);
++ BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos();
++ int k1 = k;
+
+- label39:
+- for (int i = floor1; i < ceil1; i++) {
++ while (k1 < l) {
+ float f = 0.0F;
++ int l1 = i;
+
+- for (int i1 = floor; i1 < ceil; i1++) {
+- for (int i2 = floor2; i2 < ceil2; i2++) {
+- mutableBlockPos.set(i1, i, i2);
+- FluidState fluidState = this.level().getFluidState(mutableBlockPos);
+- if (fluidState.is(FluidTags.WATER)) {
+- f = Math.max(f, fluidState.getHeight(this.level(), mutableBlockPos));
+- }
++ label35:
++ while (true) {
++ if (l1 < j) {
++ int i2 = i1;
+
+- if (f >= 1.0F) {
+- continue label39;
++ while (true) {
++ if (i2 >= j1) {
++ ++l1;
++ continue label35;
++ }
++
++ blockposition_mutableblockposition.set(l1, k1, i2);
++ FluidState fluid = this.level().getFluidState(blockposition_mutableblockposition);
++
++ if (fluid.is(FluidTags.WATER)) {
++ f = Math.max(f, fluid.getHeight(this.level(), blockposition_mutableblockposition));
++ }
++
++ if (f >= 1.0F) {
++ break;
++ }
++
++ ++i2;
+ }
++ } else if (f < 1.0F) {
++ return (float) blockposition_mutableblockposition.getY() + f;
+ }
+- }
+
+- if (f < 1.0F) {
+- return (float)mutableBlockPos.getY() + f;
++ ++k1;
++ break;
+ }
+ }
+
+- return (float)(ceil1 + 1);
++ return (float) (l + 1);
+ }
+
+ public float getGroundFriction() {
+- AABB boundingBox = this.getBoundingBox();
+- AABB aABB = new AABB(boundingBox.minX, boundingBox.minY - 0.001, boundingBox.minZ, boundingBox.maxX, boundingBox.minY, boundingBox.maxZ);
+- int i = Mth.floor(aABB.minX) - 1;
+- int i1 = Mth.ceil(aABB.maxX) + 1;
+- int i2 = Mth.floor(aABB.minY) - 1;
+- int i3 = Mth.ceil(aABB.maxY) + 1;
+- int i4 = Mth.floor(aABB.minZ) - 1;
+- int i5 = Mth.ceil(aABB.maxZ) + 1;
+- VoxelShape voxelShape = Shapes.create(aABB);
++ AABB axisalignedbb = this.getBoundingBox();
++ AABB axisalignedbb1 = new AABB(axisalignedbb.minX, axisalignedbb.minY - 0.001D, axisalignedbb.minZ, axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.maxZ);
++ int i = Mth.floor(axisalignedbb1.minX) - 1;
++ int j = Mth.ceil(axisalignedbb1.maxX) + 1;
++ int k = Mth.floor(axisalignedbb1.minY) - 1;
++ int l = Mth.ceil(axisalignedbb1.maxY) + 1;
++ int i1 = Mth.floor(axisalignedbb1.minZ) - 1;
++ int j1 = Mth.ceil(axisalignedbb1.maxZ) + 1;
++ VoxelShape voxelshape = Shapes.create(axisalignedbb1);
+ float f = 0.0F;
+- int i6 = 0;
+- BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
++ int k1 = 0;
++ BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos();
+
+- for (int i7 = i; i7 < i1; i7++) {
+- for (int i8 = i4; i8 < i5; i8++) {
+- int i9 = (i7 != i && i7 != i1 - 1 ? 0 : 1) + (i8 != i4 && i8 != i5 - 1 ? 0 : 1);
+- if (i9 != 2) {
+- for (int i10 = i2; i10 < i3; i10++) {
+- if (i9 <= 0 || i10 != i2 && i10 != i3 - 1) {
+- mutableBlockPos.set(i7, i10, i8);
+- BlockState blockState = this.level().getBlockState(mutableBlockPos);
+- if (!(blockState.getBlock() instanceof WaterlilyBlock)
+- && Shapes.joinIsNotEmpty(
+- blockState.getCollisionShape(this.level(), mutableBlockPos).move((double)i7, (double)i10, (double)i8),
+- voxelShape,
+- BooleanOp.AND
+- )) {
+- f += blockState.getBlock().getFriction();
+- i6++;
++ for (int l1 = i; l1 < j; ++l1) {
++ for (int i2 = i1; i2 < j1; ++i2) {
++ int j2 = (l1 != i && l1 != j - 1 ? 0 : 1) + (i2 != i1 && i2 != j1 - 1 ? 0 : 1);
++
++ if (j2 != 2) {
++ for (int k2 = k; k2 < l; ++k2) {
++ if (j2 <= 0 || k2 != k && k2 != l - 1) {
++ blockposition_mutableblockposition.set(l1, k2, i2);
++ IBlockData iblockdata = this.level().getBlockState(blockposition_mutableblockposition);
++
++ if (!(iblockdata.getBlock() instanceof WaterlilyBlock) && Shapes.joinIsNotEmpty(iblockdata.getCollisionShape(this.level(), blockposition_mutableblockposition).move((double) l1, (double) k2, (double) i2), voxelshape, BooleanOp.AND)) {
++ f += iblockdata.getBlock().getFriction();
++ ++k1;
+ }
+ }
+ }
+@@ -531,30 +612,33 @@
+ }
+ }
+
+- return f / (float)i6;
++ return f / (float) k1;
+ }
+
+ private boolean checkInWater() {
+- AABB boundingBox = this.getBoundingBox();
+- int floor = Mth.floor(boundingBox.minX);
+- int ceil = Mth.ceil(boundingBox.maxX);
+- int floor1 = Mth.floor(boundingBox.minY);
+- int ceil1 = Mth.ceil(boundingBox.minY + 0.001);
+- int floor2 = Mth.floor(boundingBox.minZ);
+- int ceil2 = Mth.ceil(boundingBox.maxZ);
++ AABB axisalignedbb = this.getBoundingBox();
++ int i = Mth.floor(axisalignedbb.minX);
++ int j = Mth.ceil(axisalignedbb.maxX);
++ int k = Mth.floor(axisalignedbb.minY);
++ int l = Mth.ceil(axisalignedbb.minY + 0.001D);
++ int i1 = Mth.floor(axisalignedbb.minZ);
++ int j1 = Mth.ceil(axisalignedbb.maxZ);
+ boolean flag = false;
+- this.waterLevel = -Double.MAX_VALUE;
+- BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
+
+- for (int i = floor; i < ceil; i++) {
+- for (int i1 = floor1; i1 < ceil1; i1++) {
+- for (int i2 = floor2; i2 < ceil2; i2++) {
+- mutableBlockPos.set(i, i1, i2);
+- FluidState fluidState = this.level().getFluidState(mutableBlockPos);
+- if (fluidState.is(FluidTags.WATER)) {
+- float f = (float)i1 + fluidState.getHeight(this.level(), mutableBlockPos);
+- this.waterLevel = Math.max((double)f, this.waterLevel);
+- flag |= boundingBox.minY < (double)f;
++ this.waterLevel = -1.7976931348623157E308D;
++ BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos();
++
++ for (int k1 = i; k1 < j; ++k1) {
++ for (int l1 = k; l1 < l; ++l1) {
++ for (int i2 = i1; i2 < j1; ++i2) {
++ blockposition_mutableblockposition.set(k1, l1, i2);
++ FluidState fluid = this.level().getFluidState(blockposition_mutableblockposition);
++
++ if (fluid.is(FluidTags.WATER)) {
++ float f = (float) l1 + fluid.getHeight(this.level(), blockposition_mutableblockposition);
++
++ this.waterLevel = Math.max((double) f, this.waterLevel);
++ flag |= axisalignedbb.minY < (double) f;
+ }
+ }
+ }
+@@ -564,26 +648,27 @@
+ }
+
+ @Nullable
+- private Boat.Status isUnderwater() {
+- AABB boundingBox = this.getBoundingBox();
+- double d = boundingBox.maxY + 0.001;
+- int floor = Mth.floor(boundingBox.minX);
+- int ceil = Mth.ceil(boundingBox.maxX);
+- int floor1 = Mth.floor(boundingBox.maxY);
+- int ceil1 = Mth.ceil(d);
+- int floor2 = Mth.floor(boundingBox.minZ);
+- int ceil2 = Mth.ceil(boundingBox.maxZ);
++ private Boat.EnumStatus isUnderwater() {
++ AABB axisalignedbb = this.getBoundingBox();
++ double d0 = axisalignedbb.maxY + 0.001D;
++ int i = Mth.floor(axisalignedbb.minX);
++ int j = Mth.ceil(axisalignedbb.maxX);
++ int k = Mth.floor(axisalignedbb.maxY);
++ int l = Mth.ceil(d0);
++ int i1 = Mth.floor(axisalignedbb.minZ);
++ int j1 = Mth.ceil(axisalignedbb.maxZ);
+ boolean flag = false;
+- BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
++ BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos();
+
+- for (int i = floor; i < ceil; i++) {
+- for (int i1 = floor1; i1 < ceil1; i1++) {
+- for (int i2 = floor2; i2 < ceil2; i2++) {
+- mutableBlockPos.set(i, i1, i2);
+- FluidState fluidState = this.level().getFluidState(mutableBlockPos);
+- if (fluidState.is(FluidTags.WATER) && d < (double)((float)mutableBlockPos.getY() + fluidState.getHeight(this.level(), mutableBlockPos))) {
+- if (!fluidState.isSource()) {
+- return Boat.Status.UNDER_FLOWING_WATER;
++ for (int k1 = i; k1 < j; ++k1) {
++ for (int l1 = k; l1 < l; ++l1) {
++ for (int i2 = i1; i2 < j1; ++i2) {
++ blockposition_mutableblockposition.set(k1, l1, i2);
++ FluidState fluid = this.level().getFluidState(blockposition_mutableblockposition);
++
++ if (fluid.is(FluidTags.WATER) && d0 < (double) ((float) blockposition_mutableblockposition.getY() + fluid.getHeight(this.level(), blockposition_mutableblockposition))) {
++ if (!fluid.isSource()) {
++ return Boat.EnumStatus.UNDER_FLOWING_WATER;
+ }
+
+ flag = true;
+@@ -592,58 +677,63 @@
+ }
+ }
+
+- return flag ? Boat.Status.UNDER_WATER : null;
++ return flag ? Boat.EnumStatus.UNDER_WATER : null;
+ }
+
+ private void floatBoat() {
+- double d = -0.04F;
+- double d1 = this.isNoGravity() ? 0.0 : -0.04F;
+- double d2 = 0.0;
++ double d0 = -0.03999999910593033D;
++ double d1 = this.isNoGravity() ? 0.0D : -0.03999999910593033D;
++ double d2 = 0.0D;
++
+ this.invFriction = 0.05F;
+- if (this.oldStatus == Boat.Status.IN_AIR && this.status != Boat.Status.IN_AIR && this.status != Boat.Status.ON_LAND) {
+- this.waterLevel = this.getY(1.0);
+- this.setPos(this.getX(), (double)(this.getWaterLevelAbove() - this.getBbHeight()) + 0.101, this.getZ());
+- this.setDeltaMovement(this.getDeltaMovement().multiply(1.0, 0.0, 1.0));
+- this.lastYd = 0.0;
+- this.status = Boat.Status.IN_WATER;
++ if (this.oldStatus == Boat.EnumStatus.IN_AIR && this.status != Boat.EnumStatus.IN_AIR && this.status != Boat.EnumStatus.ON_LAND) {
++ this.waterLevel = this.getY(1.0D);
++ this.setPos(this.getX(), (double) (this.getWaterLevelAbove() - this.getBbHeight()) + 0.101D, this.getZ());
++ this.setDeltaMovement(this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D));
++ this.lastYd = 0.0D;
++ this.status = Boat.EnumStatus.IN_WATER;
+ } else {
+- if (this.status == Boat.Status.IN_WATER) {
+- d2 = (this.waterLevel - this.getY()) / (double)this.getBbHeight();
++ if (this.status == Boat.EnumStatus.IN_WATER) {
++ d2 = (this.waterLevel - this.getY()) / (double) this.getBbHeight();
+ this.invFriction = 0.9F;
+- } else if (this.status == Boat.Status.UNDER_FLOWING_WATER) {
+- d1 = -7.0E-4;
++ } else if (this.status == Boat.EnumStatus.UNDER_FLOWING_WATER) {
++ d1 = -7.0E-4D;
+ this.invFriction = 0.9F;
+- } else if (this.status == Boat.Status.UNDER_WATER) {
+- d2 = 0.01F;
++ } else if (this.status == Boat.EnumStatus.UNDER_WATER) {
++ d2 = 0.009999999776482582D;
+ this.invFriction = 0.45F;
+- } else if (this.status == Boat.Status.IN_AIR) {
++ } else if (this.status == Boat.EnumStatus.IN_AIR) {
+ this.invFriction = 0.9F;
+- } else if (this.status == Boat.Status.ON_LAND) {
++ } else if (this.status == Boat.EnumStatus.ON_LAND) {
+ this.invFriction = this.landFriction;
+ if (this.getControllingPassenger() instanceof Player) {
+ this.landFriction /= 2.0F;
+ }
+ }
+
+- Vec3 deltaMovement = this.getDeltaMovement();
+- this.setDeltaMovement(deltaMovement.x * (double)this.invFriction, deltaMovement.y + d1, deltaMovement.z * (double)this.invFriction);
+- this.deltaRotation = this.deltaRotation * this.invFriction;
+- if (d2 > 0.0) {
+- Vec3 deltaMovement1 = this.getDeltaMovement();
+- this.setDeltaMovement(deltaMovement1.x, (deltaMovement1.y + d2 * 0.06153846016296973) * 0.75, deltaMovement1.z);
++ Vec3 vec3d = this.getDeltaMovement();
++
++ this.setDeltaMovement(vec3d.x * (double) this.invFriction, vec3d.y + d1, vec3d.z * (double) this.invFriction);
++ this.deltaRotation *= this.invFriction;
++ if (d2 > 0.0D) {
++ Vec3 vec3d1 = this.getDeltaMovement();
++
++ this.setDeltaMovement(vec3d1.x, (vec3d1.y + d2 * 0.06153846016296973D) * 0.75D, vec3d1.z);
+ }
+ }
++
+ }
+
+ private void controlBoat() {
+ if (this.isVehicle()) {
+ float f = 0.0F;
++
+ if (this.inputLeft) {
+- this.deltaRotation--;
++ --this.deltaRotation;
+ }
+
+ if (this.inputRight) {
+- this.deltaRotation++;
++ ++this.deltaRotation;
+ }
+
+ if (this.inputRight != this.inputLeft && !this.inputUp && !this.inputDown) {
+@@ -659,14 +749,7 @@
+ f -= 0.005F;
+ }
+
+- this.setDeltaMovement(
+- this.getDeltaMovement()
+- .add(
+- (double)(Mth.sin(-this.getYRot() * (float) (Math.PI / 180.0)) * f),
+- 0.0,
+- (double)(Mth.cos(this.getYRot() * (float) (Math.PI / 180.0)) * f)
+- )
+- );
++ this.setDeltaMovement(this.getDeltaMovement().add((double) (Mth.sin(-this.getYRot() * 0.017453292F) * f), 0.0D, (double) (Mth.cos(this.getYRot() * 0.017453292F) * f)));
+ this.setPaddleState(this.inputRight && !this.inputLeft || this.inputUp, this.inputLeft && !this.inputRight || this.inputUp);
+ }
+ }
+@@ -688,38 +771,48 @@
+ this.clampRotation(passenger);
+ if (passenger instanceof Animal && this.getPassengers().size() == this.getMaxPassengers()) {
+ int i = passenger.getId() % 2 == 0 ? 90 : 270;
+- passenger.setYBodyRot(((Animal)passenger).yBodyRot + (float)i);
+- passenger.setYHeadRot(passenger.getYHeadRot() + (float)i);
++
++ passenger.setYBodyRot(((Animal) passenger).yBodyRot + (float) i);
++ passenger.setYHeadRot(passenger.getYHeadRot() + (float) i);
+ }
++
+ }
+ }
+
+ @Override
+ public Vec3 getDismountLocationForPassenger(LivingEntity livingEntity) {
+- Vec3 collisionHorizontalEscapeVector = getCollisionHorizontalEscapeVector(
+- (double)(this.getBbWidth() * Mth.SQRT_OF_TWO), (double)livingEntity.getBbWidth(), livingEntity.getYRot()
+- );
+- double d = this.getX() + collisionHorizontalEscapeVector.x;
+- double d1 = this.getZ() + collisionHorizontalEscapeVector.z;
+- BlockPos blockPos = BlockPos.containing(d, this.getBoundingBox().maxY, d1);
+- BlockPos blockPos1 = blockPos.below();
+- if (!this.level().isWaterAt(blockPos1)) {
++ Vec3 vec3d = getCollisionHorizontalEscapeVector((double) (this.getBbWidth() * Mth.SQRT_OF_TWO), (double) livingEntity.getBbWidth(), livingEntity.getYRot());
++ double d0 = this.getX() + vec3d.x;
++ double d1 = this.getZ() + vec3d.z;
++ BlockPos blockposition = BlockPos.containing(d0, this.getBoundingBox().maxY, d1);
++ BlockPos blockposition1 = blockposition.below();
++
++ if (!this.level().isWaterAt(blockposition1)) {
+ List<Vec3> list = Lists.newArrayList();
+- double blockFloorHeight = this.level().getBlockFloorHeight(blockPos);
+- if (DismountHelper.isBlockFloorValid(blockFloorHeight)) {
+- list.add(new Vec3(d, (double)blockPos.getY() + blockFloorHeight, d1));
++ double d2 = this.level().getBlockFloorHeight(blockposition);
++
++ if (DismountHelper.isBlockFloorValid(d2)) {
++ list.add(new Vec3(d0, (double) blockposition.getY() + d2, d1));
+ }
+
+- double blockFloorHeight1 = this.level().getBlockFloorHeight(blockPos1);
+- if (DismountHelper.isBlockFloorValid(blockFloorHeight1)) {
+- list.add(new Vec3(d, (double)blockPos1.getY() + blockFloorHeight1, d1));
++ double d3 = this.level().getBlockFloorHeight(blockposition1);
++
++ if (DismountHelper.isBlockFloorValid(d3)) {
++ list.add(new Vec3(d0, (double) blockposition1.getY() + d3, d1));
+ }
+
+- for (Pose pose : livingEntity.getDismountPoses()) {
+- for (Vec3 vec3 : list) {
+- if (DismountHelper.canDismountTo(this.level(), vec3, livingEntity, pose)) {
+- livingEntity.setPose(pose);
+- return vec3;
++ UnmodifiableIterator unmodifiableiterator = livingEntity.getDismountPoses().iterator();
++
++ while (unmodifiableiterator.hasNext()) {
++ EntityPose entitypose = (EntityPose) unmodifiableiterator.next();
++ Iterator iterator = list.iterator();
++
++ while (iterator.hasNext()) {
++ Vec3 vec3d1 = (Vec3) iterator.next();
++
++ if (DismountHelper.canDismountTo(this.level(), vec3d1, livingEntity, entitypose)) {
++ livingEntity.setPose(entitypose);
++ return vec3d1;
+ }
+ }
+ }
+@@ -732,6 +825,7 @@
+ entityToUpdate.setYBodyRot(this.getYRot());
+ float f = Mth.wrapDegrees(entityToUpdate.getYRot() - this.getYRot());
+ float f1 = Mth.clamp(f, -105.0F, 105.0F);
++
+ entityToUpdate.yRotO += f1 - f;
+ entityToUpdate.setYRot(entityToUpdate.getYRot() + f1 - f);
+ entityToUpdate.setYHeadRot(entityToUpdate.getYRot());
+@@ -752,80 +846,79 @@
+ if (compound.contains("Type", 8)) {
+ this.setVariant(Boat.Type.byName(compound.getString("Type")));
+ }
++
+ }
+
+ @Override
+- public InteractionResult interact(Player player, InteractionHand hand) {
+- if (player.isSecondaryUseActive()) {
+- return InteractionResult.PASS;
+- } else if (this.outOfControlTicks < 60.0F) {
+- if (!this.level().isClientSide) {
+- return player.startRiding(this) ? InteractionResult.CONSUME : InteractionResult.PASS;
+- } else {
+- return InteractionResult.SUCCESS;
+- }
+- } else {
+- return InteractionResult.PASS;
+- }
++ public InteractionResult interact(Player player, EnumHand hand) {
++ return player.isSecondaryUseActive() ? InteractionResult.PASS : (this.outOfControlTicks < 60.0F ? (!this.level().isClientSide ? (player.startRiding(this) ? InteractionResult.CONSUME : InteractionResult.PASS) : InteractionResult.SUCCESS) : InteractionResult.PASS);
+ }
+
+ @Override
+- protected void checkFallDamage(double y, boolean onGround, BlockState state, BlockPos pos) {
++ protected void checkFallDamage(double y, boolean flag, IBlockData onGround, BlockPos state) {
+ this.lastYd = this.getDeltaMovement().y;
+ if (!this.isPassenger()) {
+- if (onGround) {
++ if (flag) {
+ if (this.fallDistance > 3.0F) {
+- if (this.status != Boat.Status.ON_LAND) {
++ if (this.status != Boat.EnumStatus.ON_LAND) {
+ this.resetFallDistance();
+ return;
+ }
+
+ this.causeFallDamage(this.fallDistance, 1.0F, this.damageSources().fall());
+ if (!this.level().isClientSide && !this.isRemoved()) {
++ // CraftBukkit start
++ Vehicle vehicle = (Vehicle) this.getBukkitEntity();
++ VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, null);
++ this.level().getCraftServer().getPluginManager().callEvent(destroyEvent);
++ if (!destroyEvent.isCancelled()) {
+ this.kill();
+ if (this.level().getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) {
+- for (int i = 0; i < 3; i++) {
+- this.spawnAtLocation(this.getVariant().getPlanks());
++ int i;
++
++ for (i = 0; i < 3; ++i) {
++ this.spawnAtLocation((IMaterial) this.getVariant().getPlanks());
+ }
+
+- for (int i = 0; i < 2; i++) {
+- this.spawnAtLocation(Items.STICK);
++ for (i = 0; i < 2; ++i) {
++ this.spawnAtLocation((IMaterial) Items.STICK);
+ }
+ }
+ }
++ } // CraftBukkit end
+ }
+
+ this.resetFallDistance();
+- } else if (!this.level().getFluidState(this.blockPosition().below()).is(FluidTags.WATER) && y < 0.0) {
+- this.fallDistance -= (float)y;
++ } else if (!this.level().getFluidState(this.blockPosition().below()).is(FluidTags.WATER) && y < 0.0D) {
++ this.fallDistance -= (float) y;
+ }
++
+ }
+ }
+
+ public boolean getPaddleState(int side) {
+- return this.entityData.get(side == 0 ? DATA_ID_PADDLE_LEFT : DATA_ID_PADDLE_RIGHT) && this.getControllingPassenger() != null;
++ return (Boolean) this.entityData.get(side == 0 ? Boat.DATA_ID_PADDLE_LEFT : Boat.DATA_ID_PADDLE_RIGHT) && this.getControllingPassenger() != null;
+ }
+
+ private void setBubbleTime(int bubbleTime) {
+- this.entityData.set(DATA_ID_BUBBLE_TIME, bubbleTime);
++ this.entityData.set(Boat.DATA_ID_BUBBLE_TIME, bubbleTime);
+ }
+
+ private int getBubbleTime() {
+- return this.entityData.get(DATA_ID_BUBBLE_TIME);
++ return (Integer) this.entityData.get(Boat.DATA_ID_BUBBLE_TIME);
+ }
+
+ public float getBubbleAngle(float partialTicks) {
+ return Mth.lerp(partialTicks, this.bubbleAngleO, this.bubbleAngle);
+ }
+
+- @Override
+ public void setVariant(Boat.Type variant) {
+- this.entityData.set(DATA_ID_TYPE, variant.ordinal());
++ this.entityData.set(Boat.DATA_ID_TYPE, variant.ordinal());
+ }
+
+ @Override
+ public Boat.Type getVariant() {
+- return Boat.Type.byId(this.entityData.get(DATA_ID_TYPE));
++ return Boat.Type.byId((Integer) this.entityData.get(Boat.DATA_ID_TYPE));
+ }
+
+ @Override
+@@ -840,7 +933,18 @@
+ @Nullable
+ @Override
+ public LivingEntity getControllingPassenger() {
+- return this.getFirstPassenger() instanceof LivingEntity livingEntity ? livingEntity : super.getControllingPassenger();
++ Entity entity = this.getFirstPassenger();
++ LivingEntity entityliving;
++
++ if (entity instanceof LivingEntity) {
++ LivingEntity entityliving1 = (LivingEntity) entity;
++
++ entityliving = entityliving1;
++ } else {
++ entityliving = super.getControllingPassenger();
++ }
++
++ return entityliving;
+ }
+
+ public void setInput(boolean inputLeft, boolean inputRight, boolean inputUp, boolean inputDown) {
+@@ -857,7 +961,7 @@
+
+ @Override
+ public boolean isUnderWater() {
+- return this.status == Boat.Status.UNDER_WATER || this.status == Boat.Status.UNDER_FLOWING_WATER;
++ return this.status == Boat.EnumStatus.UNDER_WATER || this.status == Boat.EnumStatus.UNDER_FLOWING_WATER;
+ }
+
+ @Override
+@@ -865,33 +969,18 @@
+ return new ItemStack(this.getDropItem());
+ }
+
+- public static enum Status {
+- IN_WATER,
+- UNDER_WATER,
+- UNDER_FLOWING_WATER,
+- ON_LAND,
+- IN_AIR;
+- }
+-
+ public static enum Type implements StringRepresentable {
+- OAK(Blocks.OAK_PLANKS, "oak"),
+- SPRUCE(Blocks.SPRUCE_PLANKS, "spruce"),
+- BIRCH(Blocks.BIRCH_PLANKS, "birch"),
+- JUNGLE(Blocks.JUNGLE_PLANKS, "jungle"),
+- ACACIA(Blocks.ACACIA_PLANKS, "acacia"),
+- CHERRY(Blocks.CHERRY_PLANKS, "cherry"),
+- DARK_OAK(Blocks.DARK_OAK_PLANKS, "dark_oak"),
+- MANGROVE(Blocks.MANGROVE_PLANKS, "mangrove"),
+- BAMBOO(Blocks.BAMBOO_PLANKS, "bamboo");
+
++ OAK(Blocks.OAK_PLANKS, "oak"), SPRUCE(Blocks.SPRUCE_PLANKS, "spruce"), BIRCH(Blocks.BIRCH_PLANKS, "birch"), JUNGLE(Blocks.JUNGLE_PLANKS, "jungle"), ACACIA(Blocks.ACACIA_PLANKS, "acacia"), CHERRY(Blocks.CHERRY_PLANKS, "cherry"), DARK_OAK(Blocks.DARK_OAK_PLANKS, "dark_oak"), MANGROVE(Blocks.MANGROVE_PLANKS, "mangrove"), BAMBOO(Blocks.BAMBOO_PLANKS, "bamboo");
++
+ private final String name;
+ private final Block planks;
+ public static final StringRepresentable.EnumCodec<Boat.Type> CODEC = StringRepresentable.fromEnum(Boat.Type::values);
+- private static final IntFunction<Boat.Type> BY_ID = ByIdMap.continuous(Enum::ordinal, values(), ByIdMap.OutOfBoundsStrategy.ZERO);
++ private static final IntFunction<Boat.Type> BY_ID = ByIdMap.continuous(Enum::ordinal, values(), ByIdMap.a.ZERO);
+
+- private Type(Block planks, String name) {
+- this.name = name;
+- this.planks = planks;
++ private Type(Block block, String s) {
++ this.name = s;
++ this.planks = block;
+ }
+
+ @Override
+@@ -907,17 +996,23 @@
+ return this.planks;
+ }
+
+- @Override
+ public String toString() {
+ return this.name;
+ }
+
+ public static Boat.Type byId(int id) {
+- return BY_ID.apply(id);
++ return (Boat.Type) Boat.Type.BY_ID.apply(id);
+ }
+
+ public static Boat.Type byName(String name) {
+- return CODEC.byName(name, OAK);
++ return (Boat.Type) Boat.Type.CODEC.byName(name, Boat.Type.OAK);
+ }
+ }
++
++ public static enum EnumStatus {
++
++ IN_WATER, UNDER_WATER, UNDER_FLOWING_WATER, ON_LAND, IN_AIR;
++
++ private EnumStatus() {}
++ }
+ }