package net.minecraft.world.entity;

import java.util.AbstractList;
import net.minecraft.network.syncher.EntityDataSerializers;
import org.apache.logging.log4j.LogManager;
import net.minecraft.network.chat.Style;
import net.minecraft.network.protocol.Packet;
import net.minecraft.commands.arguments.EntityAnchorArgument;
import net.minecraft.world.level.GameRules;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.level.material.PushReaction;
import java.util.function.Function;
import java.util.Collection;
import java.util.Collections;
import net.minecraft.world.level.block.Mirror;
import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.InteractionResult;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.HoverEvent;
import net.minecraft.server.level.TicketType;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.scores.PlayerTeam;
import net.minecraft.world.level.Explosion;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.levelgen.Heightmap;
import java.util.Locale;
import java.util.function.Consumer;
import net.minecraft.network.chat.ClickEvent;
import net.minecraft.world.entity.global.LightningBolt;
import com.google.common.collect.Iterables;
import net.minecraft.world.level.block.HoneyBlock;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.state.pattern.BlockPattern;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.NetherPortalBlock;
import net.minecraft.core.Vec3i;
import net.minecraft.world.phys.Vec2;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.level.ItemLike;
import net.minecraft.nbt.FloatTag;
import net.minecraft.nbt.DoubleTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.tags.Tag;
import net.minecraft.core.particles.BlockParticleOption;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.tags.FluidTags;
import net.minecraft.world.entity.vehicle.Boat;
import java.util.Iterator;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.level.LevelReader;
import net.minecraft.util.RewindableStream;
import com.google.common.collect.ImmutableSet;
import net.minecraft.world.phys.shapes.VoxelShape;
import java.util.stream.Stream;
import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.CollisionContext;
import java.util.Arrays;
import net.minecraft.world.level.block.FenceGateBlock;
import net.minecraft.tags.BlockTags;
import net.minecraft.CrashReportCategory;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.ReportedException;
import net.minecraft.CrashReport;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.item.enchantment.ProtectionEnchantment;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.network.protocol.game.ClientboundMoveEntityPacket;
import net.minecraft.world.scores.Team;
import com.google.common.collect.Sets;
import net.minecraft.util.Mth;
import com.google.common.collect.Lists;
import java.util.Set;
import java.util.UUID;
import net.minecraft.core.Direction;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.network.chat.Component;
import java.util.Optional;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.SynchedEntityData;
import java.util.Random;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.level.Level;
import javax.annotation.Nullable;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.item.ItemStack;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.logging.log4j.Logger;
import net.minecraft.commands.CommandSource;
import net.minecraft.world.Nameable;

public abstract class Entity implements Nameable, CommandSource {
    protected static final Logger LOGGER;
    private static final AtomicInteger ENTITY_COUNTER;
    private static final List<ItemStack> EMPTY_LIST;
    private static final AABB INITIAL_AABB;
    private static double viewScale;
    private final EntityType<?> type;
    private int id;
    public boolean blocksBuilding;
    private final List<Entity> passengers;
    protected int boardingCooldown;
    @Nullable
    private Entity vehicle;
    public boolean forcedLoading;
    public Level level;
    public double xo;
    public double yo;
    public double zo;
    private double x;
    private double y;
    private double z;
    private Vec3 deltaMovement;
    public float yRot;
    public float xRot;
    public float yRotO;
    public float xRotO;
    private AABB bb;
    public boolean onGround;
    public boolean horizontalCollision;
    public boolean verticalCollision;
    public boolean collision;
    public boolean hurtMarked;
    protected Vec3 stuckSpeedMultiplier;
    public boolean removed;
    public float walkDistO;
    public float walkDist;
    public float moveDist;
    public float fallDistance;
    private float nextStep;
    private float nextFlap;
    public double xOld;
    public double yOld;
    public double zOld;
    public float maxUpStep;
    public boolean noPhysics;
    public float pushthrough;
    protected final Random random;
    public int tickCount;
    private int remainingFireTicks;
    protected boolean wasInWater;
    protected double waterHeight;
    protected boolean wasUnderWater;
    protected boolean isInLava;
    public int invulnerableTime;
    protected boolean firstTick;
    protected final SynchedEntityData entityData;
    protected static final EntityDataAccessor<Byte> DATA_SHARED_FLAGS_ID;
    private static final EntityDataAccessor<Integer> DATA_AIR_SUPPLY_ID;
    private static final EntityDataAccessor<Optional<Component>> DATA_CUSTOM_NAME;
    private static final EntityDataAccessor<Boolean> DATA_CUSTOM_NAME_VISIBLE;
    private static final EntityDataAccessor<Boolean> DATA_SILENT;
    private static final EntityDataAccessor<Boolean> DATA_NO_GRAVITY;
    protected static final EntityDataAccessor<Pose> DATA_POSE;
    public boolean inChunk;
    public int xChunk;
    public int yChunk;
    public int zChunk;
    public long xp;
    public long yp;
    public long zp;
    public boolean noCulling;
    public boolean hasImpulse;
    public int changingDimensionDelay;
    protected boolean isInsidePortal;
    protected int portalTime;
    public DimensionType dimension;
    protected BlockPos portalEntranceBlock;
    protected Vec3 portalEntranceOffset;
    protected Direction portalEntranceForwards;
    private boolean invulnerable;
    protected UUID uuid;
    protected String stringUUID;
    protected boolean glowing;
    private final Set<String> tags;
    private boolean teleported;
    private final double[] pistonDeltas;
    private long pistonDeltasGameTime;
    private EntityDimensions dimensions;
    private float eyeHeight;
    
    public Entity(final EntityType<?> aku, final Level bjw) {
        this.id = Entity.ENTITY_COUNTER.incrementAndGet();
        this.passengers = Lists.newArrayList();
        this.deltaMovement = Vec3.ZERO;
        this.bb = Entity.INITIAL_AABB;
        this.stuckSpeedMultiplier = Vec3.ZERO;
        this.nextStep = 1.0f;
        this.nextFlap = 1.0f;
        this.random = new Random();
        this.remainingFireTicks = -this.getFireImmuneTicks();
        this.firstTick = true;
        this.uuid = Mth.createInsecureUUID(this.random);
        this.stringUUID = this.uuid.toString();
        this.tags = Sets.newHashSet();
        this.pistonDeltas = new double[] { 0.0, 0.0, 0.0 };
        this.type = aku;
        this.level = bjw;
        this.dimensions = aku.getDimensions();
        this.setPos(0.0, 0.0, 0.0);
        if (bjw != null) {
            this.dimension = bjw.dimension.getType();
        }
        (this.entityData = new SynchedEntityData(this)).<Byte>define(Entity.DATA_SHARED_FLAGS_ID, (Byte)0);
        this.entityData.<Integer>define(Entity.DATA_AIR_SUPPLY_ID, this.getMaxAirSupply());
        this.entityData.<Boolean>define(Entity.DATA_CUSTOM_NAME_VISIBLE, false);
        this.entityData.<Optional<Component>>define(Entity.DATA_CUSTOM_NAME, Optional.<Component>empty());
        this.entityData.<Boolean>define(Entity.DATA_SILENT, false);
        this.entityData.<Boolean>define(Entity.DATA_NO_GRAVITY, false);
        this.entityData.<Pose>define(Entity.DATA_POSE, Pose.STANDING);
        this.defineSynchedData();
        this.eyeHeight = this.getEyeHeight(Pose.STANDING, this.dimensions);
    }
    
    public int getTeamColor() {
        final Team cwn2 = this.getTeam();
        if (cwn2 != null && cwn2.getColor().getColor() != null) {
            return cwn2.getColor().getColor();
        }
        return 16777215;
    }
    
    public boolean isSpectator() {
        return false;
    }
    
    public final void unRide() {
        if (this.isVehicle()) {
            this.ejectPassengers();
        }
        if (this.isPassenger()) {
            this.stopRiding();
        }
    }
    
    public void setPacketCoordinates(final double double1, final double double2, final double double3) {
        this.xp = ClientboundMoveEntityPacket.entityToPacket(double1);
        this.yp = ClientboundMoveEntityPacket.entityToPacket(double2);
        this.zp = ClientboundMoveEntityPacket.entityToPacket(double3);
    }
    
    public EntityType<?> getType() {
        return this.type;
    }
    
    public int getId() {
        return this.id;
    }
    
    public void setId(final int integer) {
        this.id = integer;
    }
    
    public Set<String> getTags() {
        return this.tags;
    }
    
    public boolean addTag(final String string) {
        return this.tags.size() < 1024 && this.tags.add(string);
    }
    
    public boolean removeTag(final String string) {
        return this.tags.remove(string);
    }
    
    public void kill() {
        this.remove();
    }
    
    protected abstract void defineSynchedData();
    
    public SynchedEntityData getEntityData() {
        return this.entityData;
    }
    
    @Override
    public boolean equals(final Object object) {
        return object instanceof Entity && ((Entity)object).id == this.id;
    }
    
    @Override
    public int hashCode() {
        return this.id;
    }
    
    protected void resetPos() {
        if (this.level == null) {
            return;
        }
        for (double double2 = this.getY(); double2 > 0.0 && double2 < 256.0; ++double2) {
            this.setPos(this.getX(), double2, this.getZ());
            if (this.level.noCollision(this)) {
                break;
            }
        }
        this.setDeltaMovement(Vec3.ZERO);
        this.xRot = 0.0f;
    }
    
    public void remove() {
        this.removed = true;
    }
    
    protected void setPose(final Pose alj) {
        this.entityData.<Pose>set(Entity.DATA_POSE, alj);
    }
    
    public Pose getPose() {
        return this.entityData.<Pose>get(Entity.DATA_POSE);
    }
    
    protected void setRot(final float float1, final float float2) {
        this.yRot = float1 % 360.0f;
        this.xRot = float2 % 360.0f;
    }
    
    public void setPos(final double double1, final double double2, final double double3) {
        this.setPosRaw(double1, double2, double3);
        final float float8 = this.dimensions.width / 2.0f;
        final float float9 = this.dimensions.height;
        this.setBoundingBox(new AABB(double1 - float8, double2, double3 - float8, double1 + float8, double2 + float9, double3 + float8));
    }
    
    protected void reapplyPosition() {
        this.setPos(this.x, this.y, this.z);
    }
    
    public void turn(final double double1, final double double2) {
        final double double3 = double2 * 0.15;
        final double double4 = double1 * 0.15;
        this.xRot += (float)double3;
        this.yRot += (float)double4;
        this.xRot = Mth.clamp(this.xRot, -90.0f, 90.0f);
        this.xRotO += (float)double3;
        this.yRotO += (float)double4;
        this.xRotO = Mth.clamp(this.xRotO, -90.0f, 90.0f);
        if (this.vehicle != null) {
            this.vehicle.onPassengerTurned(this);
        }
    }
    
    public void tick() {
        if (!this.level.isClientSide) {
            this.setSharedFlag(6, this.isGlowing());
        }
        this.baseTick();
    }
    
    public void baseTick() {
        this.level.getProfiler().push("entityBaseTick");
        if (this.isPassenger() && this.getVehicle().removed) {
            this.stopRiding();
        }
        if (this.boardingCooldown > 0) {
            --this.boardingCooldown;
        }
        this.walkDistO = this.walkDist;
        this.xRotO = this.xRot;
        this.yRotO = this.yRot;
        this.handleNetherPortal();
        this.updateSprintingState();
        this.updateWaterState();
        if (this.level.isClientSide) {
            this.clearFire();
        }
        else if (this.remainingFireTicks > 0) {
            if (this.fireImmune()) {
                this.remainingFireTicks -= 4;
                if (this.remainingFireTicks < 0) {
                    this.clearFire();
                }
            }
            else {
                if (this.remainingFireTicks % 20 == 0) {
                    this.hurt(DamageSource.ON_FIRE, 1.0f);
                }
                --this.remainingFireTicks;
            }
        }
        if (this.isInLava()) {
            this.lavaHurt();
            this.fallDistance *= 0.5f;
        }
        if (this.getY() < -64.0) {
            this.outOfWorld();
        }
        if (!this.level.isClientSide) {
            this.setSharedFlag(0, this.remainingFireTicks > 0);
        }
        this.firstTick = false;
        this.level.getProfiler().pop();
    }
    
    protected void processDimensionDelay() {
        if (this.changingDimensionDelay > 0) {
            --this.changingDimensionDelay;
        }
    }
    
    public int getPortalWaitTime() {
        return 1;
    }
    
    protected void lavaHurt() {
        if (this.fireImmune()) {
            return;
        }
        this.setSecondsOnFire(15);
        this.hurt(DamageSource.LAVA, 4.0f);
    }
    
    public void setSecondsOnFire(final int integer) {
        int integer2 = integer * 20;
        if (this instanceof LivingEntity) {
            integer2 = ProtectionEnchantment.getFireAfterDampener((LivingEntity)this, integer2);
        }
        if (this.remainingFireTicks < integer2) {
            this.remainingFireTicks = integer2;
        }
    }
    
    public void setRemainingFireTicks(final int integer) {
        this.remainingFireTicks = integer;
    }
    
    public int getRemainingFireTicks() {
        return this.remainingFireTicks;
    }
    
    public void clearFire() {
        this.remainingFireTicks = 0;
    }
    
    protected void outOfWorld() {
        this.remove();
    }
    
    public boolean isFree(final double double1, final double double2, final double double3) {
        return this.isFree(this.getBoundingBox().move(double1, double2, double3));
    }
    
    private boolean isFree(final AABB cvf) {
        return this.level.noCollision(this, cvf) && !this.level.containsAnyLiquid(cvf);
    }
    
    public void move(final MoverType ale, Vec3 cvl) {
        if (this.noPhysics) {
            this.setBoundingBox(this.getBoundingBox().move(cvl));
            this.setLocationFromBoundingbox();
            return;
        }
        if (ale == MoverType.PISTON) {
            cvl = this.limitPistonMovement(cvl);
            if (cvl.equals(Vec3.ZERO)) {
                return;
            }
        }
        this.level.getProfiler().push("move");
        if (this.stuckSpeedMultiplier.lengthSqr() > 1.0E-7) {
            cvl = cvl.multiply(this.stuckSpeedMultiplier);
            this.stuckSpeedMultiplier = Vec3.ZERO;
            this.setDeltaMovement(Vec3.ZERO);
        }
        cvl = this.maybeBackOffFromEdge(cvl, ale);
        final Vec3 cvl2 = this.collide(cvl);
        if (cvl2.lengthSqr() > 1.0E-7) {
            this.setBoundingBox(this.getBoundingBox().move(cvl2));
            this.setLocationFromBoundingbox();
        }
        this.level.getProfiler().pop();
        this.level.getProfiler().push("rest");
        this.horizontalCollision = (!Mth.equal(cvl.x, cvl2.x) || !Mth.equal(cvl.z, cvl2.z));
        this.verticalCollision = (cvl.y != cvl2.y);
        this.onGround = (this.verticalCollision && cvl.y < 0.0);
        this.collision = (this.horizontalCollision || this.verticalCollision);
        final BlockPos fk5 = this.getOnPos();
        final BlockState byj6 = this.level.getBlockState(fk5);
        this.checkFallDamage(cvl2.y, this.onGround, byj6, fk5);
        final Vec3 cvl3 = this.getDeltaMovement();
        if (cvl.x != cvl2.x) {
            this.setDeltaMovement(0.0, cvl3.y, cvl3.z);
        }
        if (cvl.z != cvl2.z) {
            this.setDeltaMovement(cvl3.x, cvl3.y, 0.0);
        }
        final Block bph8 = byj6.getBlock();
        if (cvl.y != cvl2.y) {
            bph8.updateEntityAfterFallOn(this.level, this);
        }
        if (this.onGround && !this.isSteppingCarefully()) {
            bph8.stepOn(this.level, fk5, this);
        }
        if (this.isMovementNoisy() && !this.isPassenger()) {
            final double double9 = cvl2.x;
            double double10 = cvl2.y;
            final double double11 = cvl2.z;
            if (bph8 != Blocks.LADDER && bph8 != Blocks.SCAFFOLDING) {
                double10 = 0.0;
            }
            this.walkDist += (float)(Mth.sqrt(getHorizontalDistanceSqr(cvl2)) * 0.6);
            this.moveDist += (float)(Mth.sqrt(double9 * double9 + double10 * double10 + double11 * double11) * 0.6);
            if (this.moveDist > this.nextStep && !byj6.isAir()) {
                this.nextStep = this.nextStep();
                if (this.isInWater()) {
                    final Entity akq15 = (this.isVehicle() && this.getControllingPassenger() != null) ? this.getControllingPassenger() : this;
                    final float float16 = (akq15 == this) ? 0.35f : 0.4f;
                    final Vec3 cvl4 = akq15.getDeltaMovement();
                    float float17 = Mth.sqrt(cvl4.x * cvl4.x * 0.20000000298023224 + cvl4.y * cvl4.y + cvl4.z * cvl4.z * 0.20000000298023224) * float16;
                    if (float17 > 1.0f) {
                        float17 = 1.0f;
                    }
                    this.playSwimSound(float17);
                }
                else {
                    this.playStepSound(fk5, byj6);
                }
            }
            else if (this.moveDist > this.nextFlap && this.makeFlySound() && byj6.isAir()) {
                this.nextFlap = this.playFlySound(this.moveDist);
            }
        }
        try {
            this.isInLava = false;
            this.checkInsideBlocks();
        }
        catch (Throwable throwable9) {
            final CrashReport h10 = CrashReport.forThrowable(throwable9, "Checking entity block collision");
            final CrashReportCategory i11 = h10.addCategory("Entity being checked for collision");
            this.fillCrashReportCategory(i11);
            throw new ReportedException(h10);
        }
        this.setDeltaMovement(this.getDeltaMovement().multiply(this.getBlockSpeedFactor(), 1.0, this.getBlockSpeedFactor()));
        final boolean boolean9 = this.isInWaterRainOrBubble();
        if (this.level.containsFireBlock(this.getBoundingBox().deflate(0.001))) {
            if (!boolean9) {
                ++this.remainingFireTicks;
                if (this.remainingFireTicks == 0) {
                    this.setSecondsOnFire(8);
                }
            }
            this.burn(1);
        }
        else if (this.remainingFireTicks <= 0) {
            this.remainingFireTicks = -this.getFireImmuneTicks();
        }
        if (boolean9 && this.isOnFire()) {
            this.playSound(SoundEvents.GENERIC_EXTINGUISH_FIRE, 0.7f, 1.6f + (this.random.nextFloat() - this.random.nextFloat()) * 0.4f);
            this.remainingFireTicks = -this.getFireImmuneTicks();
        }
        this.level.getProfiler().pop();
    }
    
    protected BlockPos getOnPos() {
        final int integer2 = Mth.floor(this.x);
        final int integer3 = Mth.floor(this.y - 0.20000000298023224);
        final int integer4 = Mth.floor(this.z);
        final BlockPos fk5 = new BlockPos(integer2, integer3, integer4);
        if (this.level.getBlockState(fk5).isAir()) {
            final BlockPos fk6 = fk5.below();
            final BlockState byj7 = this.level.getBlockState(fk6);
            final Block bph8 = byj7.getBlock();
            if (bph8.is(BlockTags.FENCES) || bph8.is(BlockTags.WALLS) || bph8 instanceof FenceGateBlock) {
                return fk6;
            }
        }
        return fk5;
    }
    
    protected float getBlockJumpFactor() {
        final float float2 = this.level.getBlockState(new BlockPos(this)).getBlock().getJumpFactor();
        final float float3 = this.level.getBlockState(this.getBlockPosBelowThatAffectsMyMovement()).getBlock().getJumpFactor();
        return (float2 == 1.0) ? float3 : float2;
    }
    
    protected float getBlockSpeedFactor() {
        final Block bph2 = this.level.getBlockState(new BlockPos(this)).getBlock();
        final float float3 = bph2.getSpeedFactor();
        if (bph2 == Blocks.WATER || bph2 == Blocks.BUBBLE_COLUMN) {
            return float3;
        }
        return (float3 == 1.0) ? this.level.getBlockState(this.getBlockPosBelowThatAffectsMyMovement()).getBlock().getSpeedFactor() : float3;
    }
    
    protected BlockPos getBlockPosBelowThatAffectsMyMovement() {
        return new BlockPos(this.x, this.getBoundingBox().minY - 0.5000001, this.z);
    }
    
    protected Vec3 maybeBackOffFromEdge(final Vec3 cvl, final MoverType ale) {
        return cvl;
    }
    
    protected Vec3 limitPistonMovement(final Vec3 cvl) {
        if (cvl.lengthSqr() <= 1.0E-7) {
            return cvl;
        }
        final long long3 = this.level.getGameTime();
        if (long3 != this.pistonDeltasGameTime) {
            Arrays.fill(this.pistonDeltas, 0.0);
            this.pistonDeltasGameTime = long3;
        }
        if (cvl.x != 0.0) {
            final double double5 = this.applyPistonMovementRestriction(Direction.Axis.X, cvl.x);
            return (Math.abs(double5) <= 9.999999747378752E-6) ? Vec3.ZERO : new Vec3(double5, 0.0, 0.0);
        }
        if (cvl.y != 0.0) {
            final double double5 = this.applyPistonMovementRestriction(Direction.Axis.Y, cvl.y);
            return (Math.abs(double5) <= 9.999999747378752E-6) ? Vec3.ZERO : new Vec3(0.0, double5, 0.0);
        }
        if (cvl.z != 0.0) {
            final double double5 = this.applyPistonMovementRestriction(Direction.Axis.Z, cvl.z);
            return (Math.abs(double5) <= 9.999999747378752E-6) ? Vec3.ZERO : new Vec3(0.0, 0.0, double5);
        }
        return Vec3.ZERO;
    }
    
    private double applyPistonMovementRestriction(final Direction.Axis a, double double2) {
        final int integer5 = a.ordinal();
        final double double3 = Mth.clamp(double2 + this.pistonDeltas[integer5], -0.51, 0.51);
        double2 = double3 - this.pistonDeltas[integer5];
        this.pistonDeltas[integer5] = double3;
        return double2;
    }
    
    private Vec3 collide(final Vec3 cvl) {
        final AABB cvf3 = this.getBoundingBox();
        final CollisionContext cvq4 = CollisionContext.of(this);
        final VoxelShape cwf5 = this.level.getWorldBorder().getCollisionShape();
        final Stream<VoxelShape> stream6 = Shapes.joinIsNotEmpty(cwf5, Shapes.create(cvf3.deflate(1.0E-7)), BooleanOp.AND) ? Stream.<VoxelShape>empty() : Stream.<VoxelShape>of(cwf5);
        final Stream<VoxelShape> stream7 = this.level.getEntityCollisions(this, cvf3.expandTowards(cvl), ImmutableSet.of());
        final RewindableStream<VoxelShape> abt8 = new RewindableStream<VoxelShape>(Stream.<VoxelShape>concat(stream7, stream6));
        final Vec3 cvl2 = (cvl.lengthSqr() == 0.0) ? cvl : collideBoundingBoxHeuristically(this, cvl, cvf3, this.level, cvq4, abt8);
        final boolean boolean10 = cvl.x != cvl2.x;
        final boolean boolean11 = cvl.y != cvl2.y;
        final boolean boolean12 = cvl.z != cvl2.z;
        final boolean boolean13 = this.onGround || (boolean11 && cvl.y < 0.0);
        if (this.maxUpStep > 0.0f && boolean13 && (boolean10 || boolean12)) {
            Vec3 cvl3 = collideBoundingBoxHeuristically(this, new Vec3(cvl.x, this.maxUpStep, cvl.z), cvf3, this.level, cvq4, abt8);
            final Vec3 cvl4 = collideBoundingBoxHeuristically(this, new Vec3(0.0, this.maxUpStep, 0.0), cvf3.expandTowards(cvl.x, 0.0, cvl.z), this.level, cvq4, abt8);
            if (cvl4.y < this.maxUpStep) {
                final Vec3 cvl5 = collideBoundingBoxHeuristically(this, new Vec3(cvl.x, 0.0, cvl.z), cvf3.move(cvl4), this.level, cvq4, abt8).add(cvl4);
                if (getHorizontalDistanceSqr(cvl5) > getHorizontalDistanceSqr(cvl3)) {
                    cvl3 = cvl5;
                }
            }
            if (getHorizontalDistanceSqr(cvl3) > getHorizontalDistanceSqr(cvl2)) {
                return cvl3.add(collideBoundingBoxHeuristically(this, new Vec3(0.0, -cvl3.y + cvl.y, 0.0), cvf3.move(cvl3), this.level, cvq4, abt8));
            }
        }
        return cvl2;
    }
    
    public static double getHorizontalDistanceSqr(final Vec3 cvl) {
        return cvl.x * cvl.x + cvl.z * cvl.z;
    }
    
    public static Vec3 collideBoundingBoxHeuristically(@Nullable final Entity akq, final Vec3 cvl, final AABB cvf, final Level bjw, final CollisionContext cvq, final RewindableStream<VoxelShape> abt) {
        final boolean boolean7 = cvl.x == 0.0;
        final boolean boolean8 = cvl.y == 0.0;
        final boolean boolean9 = cvl.z == 0.0;
        if ((boolean7 && boolean8) || (boolean7 && boolean9) || (boolean8 && boolean9)) {
            return collideBoundingBox(cvl, cvf, bjw, cvq, abt);
        }
        final RewindableStream<VoxelShape> abt2 = new RewindableStream<VoxelShape>(Stream.<VoxelShape>concat(abt.getStream(), bjw.getBlockCollisions(akq, cvf.expandTowards(cvl))));
        return collideBoundingBoxLegacy(cvl, cvf, abt2);
    }
    
    public static Vec3 collideBoundingBoxLegacy(final Vec3 cvl, AABB cvf, final RewindableStream<VoxelShape> abt) {
        double double4 = cvl.x;
        double double5 = cvl.y;
        double double6 = cvl.z;
        if (double5 != 0.0) {
            double5 = Shapes.collide(Direction.Axis.Y, cvf, abt.getStream(), double5);
            if (double5 != 0.0) {
                cvf = cvf.move(0.0, double5, 0.0);
            }
        }
        final boolean boolean10 = Math.abs(double4) < Math.abs(double6);
        if (boolean10 && double6 != 0.0) {
            double6 = Shapes.collide(Direction.Axis.Z, cvf, abt.getStream(), double6);
            if (double6 != 0.0) {
                cvf = cvf.move(0.0, 0.0, double6);
            }
        }
        if (double4 != 0.0) {
            double4 = Shapes.collide(Direction.Axis.X, cvf, abt.getStream(), double4);
            if (!boolean10 && double4 != 0.0) {
                cvf = cvf.move(double4, 0.0, 0.0);
            }
        }
        if (!boolean10 && double6 != 0.0) {
            double6 = Shapes.collide(Direction.Axis.Z, cvf, abt.getStream(), double6);
        }
        return new Vec3(double4, double5, double6);
    }
    
    public static Vec3 collideBoundingBox(final Vec3 cvl, AABB cvf, final LevelReader bjz, final CollisionContext cvq, final RewindableStream<VoxelShape> abt) {
        double double6 = cvl.x;
        double double7 = cvl.y;
        double double8 = cvl.z;
        if (double7 != 0.0) {
            double7 = Shapes.collide(Direction.Axis.Y, cvf, bjz, double7, cvq, abt.getStream());
            if (double7 != 0.0) {
                cvf = cvf.move(0.0, double7, 0.0);
            }
        }
        final boolean boolean12 = Math.abs(double6) < Math.abs(double8);
        if (boolean12 && double8 != 0.0) {
            double8 = Shapes.collide(Direction.Axis.Z, cvf, bjz, double8, cvq, abt.getStream());
            if (double8 != 0.0) {
                cvf = cvf.move(0.0, 0.0, double8);
            }
        }
        if (double6 != 0.0) {
            double6 = Shapes.collide(Direction.Axis.X, cvf, bjz, double6, cvq, abt.getStream());
            if (!boolean12 && double6 != 0.0) {
                cvf = cvf.move(double6, 0.0, 0.0);
            }
        }
        if (!boolean12 && double8 != 0.0) {
            double8 = Shapes.collide(Direction.Axis.Z, cvf, bjz, double8, cvq, abt.getStream());
        }
        return new Vec3(double6, double7, double8);
    }
    
    protected float nextStep() {
        return (float)((int)this.moveDist + 1);
    }
    
    public void setLocationFromBoundingbox() {
        final AABB cvf2 = this.getBoundingBox();
        this.setPosRaw((cvf2.minX + cvf2.maxX) / 2.0, cvf2.minY, (cvf2.minZ + cvf2.maxZ) / 2.0);
    }
    
    protected SoundEvent getSwimSound() {
        return SoundEvents.GENERIC_SWIM;
    }
    
    protected SoundEvent getSwimSplashSound() {
        return SoundEvents.GENERIC_SPLASH;
    }
    
    protected SoundEvent getSwimHighSpeedSplashSound() {
        return SoundEvents.GENERIC_SPLASH;
    }
    
    protected void checkInsideBlocks() {
        final AABB cvf2 = this.getBoundingBox();
        try (final BlockPos.PooledMutableBlockPos b3 = BlockPos.PooledMutableBlockPos.acquire(cvf2.minX + 0.001, cvf2.minY + 0.001, cvf2.minZ + 0.001);
             final BlockPos.PooledMutableBlockPos b4 = BlockPos.PooledMutableBlockPos.acquire(cvf2.maxX - 0.001, cvf2.maxY - 0.001, cvf2.maxZ - 0.001);
             final BlockPos.PooledMutableBlockPos b5 = BlockPos.PooledMutableBlockPos.acquire()) {
            if (this.level.hasChunksAt(b3, b4)) {
                for (int integer9 = b3.getX(); integer9 <= b4.getX(); ++integer9) {
                    for (int integer10 = b3.getY(); integer10 <= b4.getY(); ++integer10) {
                        for (int integer11 = b3.getZ(); integer11 <= b4.getZ(); ++integer11) {
                            b5.set(integer9, integer10, integer11);
                            final BlockState byj12 = this.level.getBlockState(b5);
                            try {
                                byj12.entityInside(this.level, b5, this);
                                this.onInsideBlock(byj12);
                            }
                            catch (Throwable throwable13) {
                                final CrashReport h14 = CrashReport.forThrowable(throwable13, "Colliding entity with block");
                                final CrashReportCategory i15 = h14.addCategory("Block being collided with");
                                CrashReportCategory.populateBlockDetails(i15, b5, byj12);
                                throw new ReportedException(h14);
                            }
                        }
                    }
                }
            }
        }
    }
    
    protected void onInsideBlock(final BlockState byj) {
    }
    
    protected void playStepSound(final BlockPos fk, final BlockState byj) {
        if (byj.getMaterial().isLiquid()) {
            return;
        }
        final BlockState byj2 = this.level.getBlockState(fk.above());
        final SoundType bum5 = (byj2.getBlock() == Blocks.SNOW) ? byj2.getSoundType() : byj.getSoundType();
        this.playSound(bum5.getStepSound(), bum5.getVolume() * 0.15f, bum5.getPitch());
    }
    
    protected void playSwimSound(final float float1) {
        this.playSound(this.getSwimSound(), float1, 1.0f + (this.random.nextFloat() - this.random.nextFloat()) * 0.4f);
    }
    
    protected float playFlySound(final float float1) {
        return 0.0f;
    }
    
    protected boolean makeFlySound() {
        return false;
    }
    
    public void playSound(final SoundEvent aah, final float float2, final float float3) {
        if (!this.isSilent()) {
            this.level.playSound(null, this.getX(), this.getY(), this.getZ(), aah, this.getSoundSource(), float2, float3);
        }
    }
    
    public boolean isSilent() {
        return this.entityData.<Boolean>get(Entity.DATA_SILENT);
    }
    
    public void setSilent(final boolean boolean1) {
        this.entityData.<Boolean>set(Entity.DATA_SILENT, boolean1);
    }
    
    public boolean isNoGravity() {
        return this.entityData.<Boolean>get(Entity.DATA_NO_GRAVITY);
    }
    
    public void setNoGravity(final boolean boolean1) {
        this.entityData.<Boolean>set(Entity.DATA_NO_GRAVITY, boolean1);
    }
    
    protected boolean isMovementNoisy() {
        return true;
    }
    
    protected void checkFallDamage(final double double1, final boolean boolean2, final BlockState byj, final BlockPos fk) {
        if (boolean2) {
            if (this.fallDistance > 0.0f) {
                byj.getBlock().fallOn(this.level, fk, this, this.fallDistance);
            }
            this.fallDistance = 0.0f;
        }
        else if (double1 < 0.0) {
            this.fallDistance -= (float)double1;
        }
    }
    
    @Nullable
    public AABB getCollideBox() {
        return null;
    }
    
    protected void burn(final int integer) {
        if (!this.fireImmune()) {
            this.hurt(DamageSource.IN_FIRE, (float)integer);
        }
    }
    
    public final boolean fireImmune() {
        return this.getType().fireImmune();
    }
    
    public boolean causeFallDamage(final float float1, final float float2) {
        if (this.isVehicle()) {
            for (final Entity akq5 : this.getPassengers()) {
                akq5.causeFallDamage(float1, float2);
            }
        }
        return false;
    }
    
    public boolean isInWater() {
        return this.wasInWater;
    }
    
    private boolean isInRain() {
        try (final BlockPos.PooledMutableBlockPos b2 = BlockPos.PooledMutableBlockPos.acquire(this)) {
            return this.level.isRainingAt(b2) || this.level.isRainingAt(b2.set(this.getX(), this.getY() + this.dimensions.height, this.getZ()));
        }
    }
    
    private boolean isInBubbleColumn() {
        return this.level.getBlockState(new BlockPos(this)).getBlock() == Blocks.BUBBLE_COLUMN;
    }
    
    public boolean isInWaterOrRain() {
        return this.isInWater() || this.isInRain();
    }
    
    public boolean isInWaterRainOrBubble() {
        return this.isInWater() || this.isInRain() || this.isInBubbleColumn();
    }
    
    public boolean isInWaterOrBubble() {
        return this.isInWater() || this.isInBubbleColumn();
    }
    
    public boolean isUnderWater() {
        return this.wasUnderWater && this.isInWater();
    }
    
    private void updateWaterState() {
        this.updateInWaterState();
        this.updateUnderWaterState();
        this.updateSwimming();
    }
    
    public void updateSwimming() {
        if (this.isSwimming()) {
            this.setSwimming(this.isSprinting() && this.isInWater() && !this.isPassenger());
        }
        else {
            this.setSwimming(this.isSprinting() && this.isUnderWater() && !this.isPassenger());
        }
    }
    
    public boolean updateInWaterState() {
        if (this.getVehicle() instanceof Boat) {
            this.wasInWater = false;
        }
        else if (this.checkAndHandleWater(FluidTags.WATER)) {
            if (!this.wasInWater && !this.firstTick) {
                this.doWaterSplashEffect();
            }
            this.fallDistance = 0.0f;
            this.wasInWater = true;
            this.clearFire();
        }
        else {
            this.wasInWater = false;
        }
        return this.wasInWater;
    }
    
    private void updateUnderWaterState() {
        this.wasUnderWater = this.isUnderLiquid(FluidTags.WATER, true);
    }
    
    protected void doWaterSplashEffect() {
        final Entity akq2 = (this.isVehicle() && this.getControllingPassenger() != null) ? this.getControllingPassenger() : this;
        final float float3 = (akq2 == this) ? 0.2f : 0.9f;
        final Vec3 cvl4 = akq2.getDeltaMovement();
        float float4 = Mth.sqrt(cvl4.x * cvl4.x * 0.20000000298023224 + cvl4.y * cvl4.y + cvl4.z * cvl4.z * 0.20000000298023224) * float3;
        if (float4 > 1.0f) {
            float4 = 1.0f;
        }
        if (float4 < 0.25) {
            this.playSound(this.getSwimSplashSound(), float4, 1.0f + (this.random.nextFloat() - this.random.nextFloat()) * 0.4f);
        }
        else {
            this.playSound(this.getSwimHighSpeedSplashSound(), float4, 1.0f + (this.random.nextFloat() - this.random.nextFloat()) * 0.4f);
        }
        final float float5 = (float)Mth.floor(this.getY());
        for (int integer7 = 0; integer7 < 1.0f + this.dimensions.width * 20.0f; ++integer7) {
            final float float6 = (this.random.nextFloat() * 2.0f - 1.0f) * this.dimensions.width;
            final float float7 = (this.random.nextFloat() * 2.0f - 1.0f) * this.dimensions.width;
            this.level.addParticle(ParticleTypes.BUBBLE, this.getX() + float6, float5 + 1.0f, this.getZ() + float7, cvl4.x, cvl4.y - this.random.nextFloat() * 0.2f, cvl4.z);
        }
        for (int integer7 = 0; integer7 < 1.0f + this.dimensions.width * 20.0f; ++integer7) {
            final float float6 = (this.random.nextFloat() * 2.0f - 1.0f) * this.dimensions.width;
            final float float7 = (this.random.nextFloat() * 2.0f - 1.0f) * this.dimensions.width;
            this.level.addParticle(ParticleTypes.SPLASH, this.getX() + float6, float5 + 1.0f, this.getZ() + float7, cvl4.x, cvl4.y, cvl4.z);
        }
    }
    
    public void updateSprintingState() {
        if (this.isSprinting() && !this.isInWater()) {
            this.doSprintParticleEffect();
        }
    }
    
    protected void doSprintParticleEffect() {
        final int integer2 = Mth.floor(this.getX());
        final int integer3 = Mth.floor(this.getY() - 0.20000000298023224);
        final int integer4 = Mth.floor(this.getZ());
        final BlockPos fk5 = new BlockPos(integer2, integer3, integer4);
        final BlockState byj6 = this.level.getBlockState(fk5);
        if (byj6.getRenderShape() != RenderShape.INVISIBLE) {
            final Vec3 cvl7 = this.getDeltaMovement();
            this.level.addParticle(new BlockParticleOption(ParticleTypes.BLOCK, byj6), this.getX() + (this.random.nextFloat() - 0.5) * this.dimensions.width, this.getY() + 0.1, this.getZ() + (this.random.nextFloat() - 0.5) * this.dimensions.width, cvl7.x * -4.0, 1.5, cvl7.z * -4.0);
        }
    }
    
    public boolean isUnderLiquid(final Tag<Fluid> aaz) {
        return this.isUnderLiquid(aaz, false);
    }
    
    public boolean isUnderLiquid(final Tag<Fluid> aaz, final boolean boolean2) {
        if (this.getVehicle() instanceof Boat) {
            return false;
        }
        final double double4 = this.getEyeY();
        final BlockPos fk6 = new BlockPos(this.getX(), double4, this.getZ());
        if (boolean2 && !this.level.hasChunk(fk6.getX() >> 4, fk6.getZ() >> 4)) {
            return false;
        }
        final FluidState coj7 = this.level.getFluidState(fk6);
        return coj7.is(aaz) && double4 < fk6.getY() + (coj7.getHeight(this.level, fk6) + 0.11111111f);
    }
    
    public void setInLava() {
        this.isInLava = true;
    }
    
    public boolean isInLava() {
        return this.isInLava;
    }
    
    public void moveRelative(final float float1, final Vec3 cvl) {
        final Vec3 cvl2 = getInputVector(cvl, float1, this.yRot);
        this.setDeltaMovement(this.getDeltaMovement().add(cvl2));
    }
    
    private static Vec3 getInputVector(final Vec3 cvl, final float float2, final float float3) {
        final double double4 = cvl.lengthSqr();
        if (double4 < 1.0E-7) {
            return Vec3.ZERO;
        }
        final Vec3 cvl2 = ((double4 > 1.0) ? cvl.normalize() : cvl).scale(float2);
        final float float4 = Mth.sin(float3 * 0.017453292f);
        final float float5 = Mth.cos(float3 * 0.017453292f);
        return new Vec3(cvl2.x * float5 - cvl2.z * float4, cvl2.y, cvl2.z * float5 + cvl2.x * float4);
    }
    
    public float getBrightness() {
        final BlockPos.MutableBlockPos a2 = new BlockPos.MutableBlockPos(this.getX(), 0.0, this.getZ());
        if (this.level.hasChunkAt(a2)) {
            a2.setY(Mth.floor(this.getEyeY()));
            return this.level.getBrightness(a2);
        }
        return 0.0f;
    }
    
    public void setLevel(final Level bjw) {
        this.level = bjw;
    }
    
    public void absMoveTo(final double double1, final double double2, final double double3, final float float4, final float float5) {
        final double double4 = Mth.clamp(double1, -3.0E7, 3.0E7);
        final double double5 = Mth.clamp(double3, -3.0E7, 3.0E7);
        this.setPos(this.xo = double4, this.yo = double2, this.zo = double5);
        this.yRot = float4 % 360.0f;
        this.xRot = Mth.clamp(float5, -90.0f, 90.0f) % 360.0f;
        this.yRotO = this.yRot;
        this.xRotO = this.xRot;
    }
    
    public void moveTo(final BlockPos fk, final float float2, final float float3) {
        this.moveTo(fk.getX() + 0.5, fk.getY(), fk.getZ() + 0.5, float2, float3);
    }
    
    public void moveTo(final double double1, final double double2, final double double3, final float float4, final float float5) {
        this.setPosAndOldPos(double1, double2, double3);
        this.yRot = float4;
        this.xRot = float5;
        this.reapplyPosition();
    }
    
    public void setPosAndOldPos(final double double1, final double double2, final double double3) {
        this.setPosRaw(double1, double2, double3);
        this.xo = double1;
        this.yo = double2;
        this.zo = double3;
        this.xOld = double1;
        this.yOld = double2;
        this.zOld = double3;
    }
    
    public float distanceTo(final Entity akq) {
        final float float3 = (float)(this.getX() - akq.getX());
        final float float4 = (float)(this.getY() - akq.getY());
        final float float5 = (float)(this.getZ() - akq.getZ());
        return Mth.sqrt(float3 * float3 + float4 * float4 + float5 * float5);
    }
    
    public double distanceToSqr(final double double1, final double double2, final double double3) {
        final double double4 = this.getX() - double1;
        final double double5 = this.getY() - double2;
        final double double6 = this.getZ() - double3;
        return double4 * double4 + double5 * double5 + double6 * double6;
    }
    
    public double distanceToSqr(final Entity akq) {
        return this.distanceToSqr(akq.position());
    }
    
    public double distanceToSqr(final Vec3 cvl) {
        final double double3 = this.getX() - cvl.x;
        final double double4 = this.getY() - cvl.y;
        final double double5 = this.getZ() - cvl.z;
        return double3 * double3 + double4 * double4 + double5 * double5;
    }
    
    public void playerTouch(final Player ayj) {
    }
    
    public void push(final Entity akq) {
        if (this.isPassengerOfSameVehicle(akq)) {
            return;
        }
        if (akq.noPhysics || this.noPhysics) {
            return;
        }
        double double3 = akq.getX() - this.getX();
        double double4 = akq.getZ() - this.getZ();
        double double5 = Mth.absMax(double3, double4);
        if (double5 >= 0.009999999776482582) {
            double5 = Mth.sqrt(double5);
            double3 /= double5;
            double4 /= double5;
            double double6 = 1.0 / double5;
            if (double6 > 1.0) {
                double6 = 1.0;
            }
            double3 *= double6;
            double4 *= double6;
            double3 *= 0.05000000074505806;
            double4 *= 0.05000000074505806;
            double3 *= 1.0f - this.pushthrough;
            double4 *= 1.0f - this.pushthrough;
            if (!this.isVehicle()) {
                this.push(-double3, 0.0, -double4);
            }
            if (!akq.isVehicle()) {
                akq.push(double3, 0.0, double4);
            }
        }
    }
    
    public void push(final double double1, final double double2, final double double3) {
        this.setDeltaMovement(this.getDeltaMovement().add(double1, double2, double3));
        this.hasImpulse = true;
    }
    
    protected void markHurt() {
        this.hurtMarked = true;
    }
    
    public boolean hurt(final DamageSource ajz, final float float2) {
        if (this.isInvulnerableTo(ajz)) {
            return false;
        }
        this.markHurt();
        return false;
    }
    
    public final Vec3 getViewVector(final float float1) {
        return this.calculateViewVector(this.getViewXRot(float1), this.getViewYRot(float1));
    }
    
    public float getViewXRot(final float float1) {
        if (float1 == 1.0f) {
            return this.xRot;
        }
        return Mth.lerp(float1, this.xRotO, this.xRot);
    }
    
    public float getViewYRot(final float float1) {
        if (float1 == 1.0f) {
            return this.yRot;
        }
        return Mth.lerp(float1, this.yRotO, this.yRot);
    }
    
    protected final Vec3 calculateViewVector(final float float1, final float float2) {
        final float float3 = float1 * 0.017453292f;
        final float float4 = -float2 * 0.017453292f;
        final float float5 = Mth.cos(float4);
        final float float6 = Mth.sin(float4);
        final float float7 = Mth.cos(float3);
        final float float8 = Mth.sin(float3);
        return new Vec3(float6 * float7, -float8, float5 * float7);
    }
    
    public final Vec3 getUpVector(final float float1) {
        return this.calculateUpVector(this.getViewXRot(float1), this.getViewYRot(float1));
    }
    
    protected final Vec3 calculateUpVector(final float float1, final float float2) {
        return this.calculateViewVector(float1 - 90.0f, float2);
    }
    
    public final Vec3 getEyePosition(final float float1) {
        if (float1 == 1.0f) {
            return new Vec3(this.getX(), this.getEyeY(), this.getZ());
        }
        final double double3 = Mth.lerp(float1, this.xo, this.getX());
        final double double4 = Mth.lerp(float1, this.yo, this.getY()) + this.getEyeHeight();
        final double double5 = Mth.lerp(float1, this.zo, this.getZ());
        return new Vec3(double3, double4, double5);
    }
    
    public HitResult pick(final double double1, final float float2, final boolean boolean3) {
        final Vec3 cvl6 = this.getEyePosition(float2);
        final Vec3 cvl7 = this.getViewVector(float2);
        final Vec3 cvl8 = cvl6.add(cvl7.x * double1, cvl7.y * double1, cvl7.z * double1);
        return this.level.clip(new ClipContext(cvl6, cvl8, ClipContext.Block.OUTLINE, boolean3 ? ClipContext.Fluid.ANY : ClipContext.Fluid.NONE, this));
    }
    
    public boolean isPickable() {
        return false;
    }
    
    public boolean isPushable() {
        return false;
    }
    
    public void awardKillScore(final Entity akq, final int integer, final DamageSource ajz) {
        if (akq instanceof ServerPlayer) {
            CriteriaTriggers.ENTITY_KILLED_PLAYER.trigger((ServerPlayer)akq, this, ajz);
        }
    }
    
    public boolean shouldRender(final double double1, final double double2, final double double3) {
        final double double4 = this.getX() - double1;
        final double double5 = this.getY() - double2;
        final double double6 = this.getZ() - double3;
        final double double7 = double4 * double4 + double5 * double5 + double6 * double6;
        return this.shouldRenderAtSqrDistance(double7);
    }
    
    public boolean shouldRenderAtSqrDistance(final double double1) {
        double double2 = this.getBoundingBox().getSize();
        if (Double.isNaN(double2)) {
            double2 = 1.0;
        }
        double2 *= 64.0 * Entity.viewScale;
        return double1 < double2 * double2;
    }
    
    public boolean saveAsPassenger(final CompoundTag jt) {
        final String string3 = this.getEncodeId();
        if (this.removed || string3 == null) {
            return false;
        }
        jt.putString("id", string3);
        this.saveWithoutId(jt);
        return true;
    }
    
    public boolean save(final CompoundTag jt) {
        return !this.isPassenger() && this.saveAsPassenger(jt);
    }
    
    public CompoundTag saveWithoutId(final CompoundTag jt) {
        try {
            jt.put("Pos", this.newDoubleList(this.getX(), this.getY(), this.getZ()));
            final Vec3 cvl3 = this.getDeltaMovement();
            jt.put("Motion", this.newDoubleList(cvl3.x, cvl3.y, cvl3.z));
            jt.put("Rotation", this.newFloatList(this.yRot, this.xRot));
            jt.putFloat("FallDistance", this.fallDistance);
            jt.putShort("Fire", (short)this.remainingFireTicks);
            jt.putShort("Air", (short)this.getAirSupply());
            jt.putBoolean("OnGround", this.onGround);
            jt.putInt("Dimension", this.dimension.getId());
            jt.putBoolean("Invulnerable", this.invulnerable);
            jt.putInt("PortalCooldown", this.changingDimensionDelay);
            jt.putUUID("UUID", this.getUUID());
            final Component lf4 = this.getCustomName();
            if (lf4 != null) {
                jt.putString("CustomName", Component.Serializer.toJson(lf4));
            }
            if (this.isCustomNameVisible()) {
                jt.putBoolean("CustomNameVisible", this.isCustomNameVisible());
            }
            if (this.isSilent()) {
                jt.putBoolean("Silent", this.isSilent());
            }
            if (this.isNoGravity()) {
                jt.putBoolean("NoGravity", this.isNoGravity());
            }
            if (this.glowing) {
                jt.putBoolean("Glowing", this.glowing);
            }
            if (!this.tags.isEmpty()) {
                final ListTag jz5 = new ListTag();
                for (final String string7 : this.tags) {
                    ((AbstractList<StringTag>)jz5).add(StringTag.valueOf(string7));
                }
                jt.put("Tags", jz5);
            }
            this.addAdditionalSaveData(jt);
            if (this.isVehicle()) {
                final ListTag jz5 = new ListTag();
                for (final Entity akq7 : this.getPassengers()) {
                    final CompoundTag jt2 = new CompoundTag();
                    if (akq7.saveAsPassenger(jt2)) {
                        ((AbstractList<CompoundTag>)jz5).add(jt2);
                    }
                }
                if (!jz5.isEmpty()) {
                    jt.put("Passengers", jz5);
                }
            }
        }
        catch (Throwable throwable3) {
            final CrashReport h4 = CrashReport.forThrowable(throwable3, "Saving entity NBT");
            final CrashReportCategory i5 = h4.addCategory("Entity being saved");
            this.fillCrashReportCategory(i5);
            throw new ReportedException(h4);
        }
        return jt;
    }
    
    public void load(final CompoundTag jt) {
        try {
            final ListTag jz3 = jt.getList("Pos", 6);
            final ListTag jz4 = jt.getList("Motion", 6);
            final ListTag jz5 = jt.getList("Rotation", 5);
            final double double6 = jz4.getDouble(0);
            final double double7 = jz4.getDouble(1);
            final double double8 = jz4.getDouble(2);
            this.setDeltaMovement((Math.abs(double6) > 10.0) ? 0.0 : double6, (Math.abs(double7) > 10.0) ? 0.0 : double7, (Math.abs(double8) > 10.0) ? 0.0 : double8);
            this.setPosAndOldPos(jz3.getDouble(0), jz3.getDouble(1), jz3.getDouble(2));
            this.yRot = jz5.getFloat(0);
            this.xRot = jz5.getFloat(1);
            this.yRotO = this.yRot;
            this.xRotO = this.xRot;
            this.setYHeadRot(this.yRot);
            this.setYBodyRot(this.yRot);
            this.fallDistance = jt.getFloat("FallDistance");
            this.remainingFireTicks = jt.getShort("Fire");
            this.setAirSupply(jt.getShort("Air"));
            this.onGround = jt.getBoolean("OnGround");
            if (jt.contains("Dimension")) {
                this.dimension = DimensionType.getById(jt.getInt("Dimension"));
            }
            this.invulnerable = jt.getBoolean("Invulnerable");
            this.changingDimensionDelay = jt.getInt("PortalCooldown");
            if (jt.hasUUID("UUID")) {
                this.uuid = jt.getUUID("UUID");
                this.stringUUID = this.uuid.toString();
            }
            if (!Double.isFinite(this.getX()) || !Double.isFinite(this.getY()) || !Double.isFinite(this.getZ())) {
                throw new IllegalStateException("Entity has invalid position");
            }
            if (!Double.isFinite(this.yRot) || !Double.isFinite(this.xRot)) {
                throw new IllegalStateException("Entity has invalid rotation");
            }
            this.reapplyPosition();
            this.setRot(this.yRot, this.xRot);
            if (jt.contains("CustomName", 8)) {
                this.setCustomName(Component.Serializer.fromJson(jt.getString("CustomName")));
            }
            this.setCustomNameVisible(jt.getBoolean("CustomNameVisible"));
            this.setSilent(jt.getBoolean("Silent"));
            this.setNoGravity(jt.getBoolean("NoGravity"));
            this.setGlowing(jt.getBoolean("Glowing"));
            if (jt.contains("Tags", 9)) {
                this.tags.clear();
                final ListTag jz6 = jt.getList("Tags", 8);
                for (int integer13 = Math.min(jz6.size(), 1024), integer14 = 0; integer14 < integer13; ++integer14) {
                    this.tags.add(jz6.getString(integer14));
                }
            }
            this.readAdditionalSaveData(jt);
            if (this.repositionEntityAfterLoad()) {
                this.reapplyPosition();
            }
        }
        catch (Throwable throwable3) {
            final CrashReport h4 = CrashReport.forThrowable(throwable3, "Loading entity NBT");
            final CrashReportCategory i5 = h4.addCategory("Entity being loaded");
            this.fillCrashReportCategory(i5);
            throw new ReportedException(h4);
        }
    }
    
    protected boolean repositionEntityAfterLoad() {
        return true;
    }
    
    @Nullable
    protected final String getEncodeId() {
        final EntityType<?> aku2 = this.getType();
        final ResourceLocation sm3 = EntityType.getKey(aku2);
        return (!aku2.canSerialize() || sm3 == null) ? null : sm3.toString();
    }
    
    protected abstract void readAdditionalSaveData(final CompoundTag jt);
    
    protected abstract void addAdditionalSaveData(final CompoundTag jt);
    
    protected ListTag newDoubleList(final double... arr) {
        final ListTag jz3 = new ListTag();
        for (final double double7 : arr) {
            ((AbstractList<DoubleTag>)jz3).add(DoubleTag.valueOf(double7));
        }
        return jz3;
    }
    
    protected ListTag newFloatList(final float... arr) {
        final ListTag jz3 = new ListTag();
        for (final float float7 : arr) {
            ((AbstractList<FloatTag>)jz3).add(FloatTag.valueOf(float7));
        }
        return jz3;
    }
    
    @Nullable
    public ItemEntity spawnAtLocation(final ItemLike bjv) {
        return this.spawnAtLocation(bjv, 0);
    }
    
    @Nullable
    public ItemEntity spawnAtLocation(final ItemLike bjv, final int integer) {
        return this.spawnAtLocation(new ItemStack(bjv), (float)integer);
    }
    
    @Nullable
    public ItemEntity spawnAtLocation(final ItemStack ben) {
        return this.spawnAtLocation(ben, 0.0f);
    }
    
    @Nullable
    public ItemEntity spawnAtLocation(final ItemStack ben, final float float2) {
        if (ben.isEmpty()) {
            return null;
        }
        if (this.level.isClientSide) {
            return null;
        }
        final ItemEntity awb4 = new ItemEntity(this.level, this.getX(), this.getY() + float2, this.getZ(), ben);
        awb4.setDefaultPickUpDelay();
        this.level.addFreshEntity(awb4);
        return awb4;
    }
    
    public boolean isAlive() {
        return !this.removed;
    }
    
    public boolean isInWall() {
        if (this.noPhysics) {
            return false;
        }
        try (final BlockPos.PooledMutableBlockPos b2 = BlockPos.PooledMutableBlockPos.acquire()) {
            for (int integer4 = 0; integer4 < 8; ++integer4) {
                final int integer5 = Mth.floor(this.getY() + ((integer4 >> 0) % 2 - 0.5f) * 0.1f + this.eyeHeight);
                final int integer6 = Mth.floor(this.getX() + ((integer4 >> 1) % 2 - 0.5f) * this.dimensions.width * 0.8f);
                final int integer7 = Mth.floor(this.getZ() + ((integer4 >> 2) % 2 - 0.5f) * this.dimensions.width * 0.8f);
                if (b2.getX() != integer6 || b2.getY() != integer5 || b2.getZ() != integer7) {
                    b2.set(integer6, integer5, integer7);
                    if (this.level.getBlockState(b2).isSuffocating(this.level, b2)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    
    public boolean interact(final Player ayj, final InteractionHand ajk) {
        return false;
    }
    
    @Nullable
    public AABB getCollideAgainstBox(final Entity akq) {
        return null;
    }
    
    public void rideTick() {
        this.setDeltaMovement(Vec3.ZERO);
        this.tick();
        if (!this.isPassenger()) {
            return;
        }
        this.getVehicle().positionRider(this);
    }
    
    public void positionRider(final Entity akq) {
        this.positionRider(akq, Entity::setPos);
    }
    
    public void positionRider(final Entity akq, final MoveCallback a) {
        if (!this.hasPassenger(akq)) {
            return;
        }
        a.accept(akq, this.getX(), this.getY() + this.getRideHeight() + akq.getRidingHeight(), this.getZ());
    }
    
    public void onPassengerTurned(final Entity akq) {
    }
    
    public double getRidingHeight() {
        return 0.0;
    }
    
    public double getRideHeight() {
        return this.dimensions.height * 0.75;
    }
    
    public boolean startRiding(final Entity akq) {
        return this.startRiding(akq, false);
    }
    
    public boolean showVehicleHealth() {
        return this instanceof LivingEntity;
    }
    
    public boolean startRiding(final Entity akq, final boolean boolean2) {
        for (Entity akq2 = akq; akq2.vehicle != null; akq2 = akq2.vehicle) {
            if (akq2.vehicle == this) {
                return false;
            }
        }
        if (!boolean2 && (!this.canRide(akq) || !akq.canAddPassenger(this))) {
            return false;
        }
        if (this.isPassenger()) {
            this.stopRiding();
        }
        (this.vehicle = akq).addPassenger(this);
        return true;
    }
    
    protected boolean canRide(final Entity akq) {
        return this.boardingCooldown <= 0;
    }
    
    protected boolean canEnterPose(final Pose alj) {
        return this.level.noCollision(this, this.getBoundingBoxForPose(alj));
    }
    
    public void ejectPassengers() {
        for (int integer2 = this.passengers.size() - 1; integer2 >= 0; --integer2) {
            this.passengers.get(integer2).stopRiding();
        }
    }
    
    public void stopRiding() {
        if (this.vehicle != null) {
            final Entity akq2 = this.vehicle;
            this.vehicle = null;
            akq2.removePassenger(this);
        }
    }
    
    protected void addPassenger(final Entity akq) {
        if (akq.getVehicle() != this) {
            throw new IllegalStateException("Use x.startRiding(y), not y.addPassenger(x)");
        }
        if (!this.level.isClientSide && akq instanceof Player && !(this.getControllingPassenger() instanceof Player)) {
            this.passengers.add(0, akq);
        }
        else {
            this.passengers.add(akq);
        }
    }
    
    protected void removePassenger(final Entity akq) {
        if (akq.getVehicle() == this) {
            throw new IllegalStateException("Use x.stopRiding(y), not y.removePassenger(x)");
        }
        this.passengers.remove(akq);
        akq.boardingCooldown = 60;
    }
    
    protected boolean canAddPassenger(final Entity akq) {
        return this.getPassengers().size() < 1;
    }
    
    public void lerpTo(final double double1, final double double2, final double double3, final float float4, final float float5, final int integer, final boolean boolean7) {
        this.setPos(double1, double2, double3);
        this.setRot(float4, float5);
    }
    
    public void lerpHeadTo(final float float1, final int integer) {
        this.setYHeadRot(float1);
    }
    
    public float getPickRadius() {
        return 0.0f;
    }
    
    public Vec3 getLookAngle() {
        return this.calculateViewVector(this.xRot, this.yRot);
    }
    
    public Vec2 getRotationVector() {
        return new Vec2(this.xRot, this.yRot);
    }
    
    public Vec3 getForward() {
        return Vec3.directionFromRotation(this.getRotationVector());
    }
    
    public void handleInsidePortal(final BlockPos fk) {
        if (this.changingDimensionDelay > 0) {
            this.changingDimensionDelay = this.getDimensionChangingDelay();
            return;
        }
        if (!this.level.isClientSide && !fk.equals(this.portalEntranceBlock)) {
            this.portalEntranceBlock = new BlockPos(fk);
            final NetherPortalBlock netherPortalBlock = (NetherPortalBlock)Blocks.NETHER_PORTAL;
            final BlockPattern.BlockPatternMatch b3 = NetherPortalBlock.getPortalShape(this.level, this.portalEntranceBlock);
            final double double4 = (b3.getForwards().getAxis() == Direction.Axis.X) ? b3.getFrontTopLeft().getZ() : ((double)b3.getFrontTopLeft().getX());
            final double double5 = Math.abs(Mth.pct(((b3.getForwards().getAxis() == Direction.Axis.X) ? this.getZ() : this.getX()) - (double)((b3.getForwards().getClockWise().getAxisDirection() == Direction.AxisDirection.NEGATIVE) ? 1 : 0), double4, double4 - b3.getWidth()));
            final double double6 = Mth.pct(this.getY() - 1.0, b3.getFrontTopLeft().getY(), b3.getFrontTopLeft().getY() - b3.getHeight());
            this.portalEntranceOffset = new Vec3(double5, double6, 0.0);
            this.portalEntranceForwards = b3.getForwards();
        }
        this.isInsidePortal = true;
    }
    
    protected void handleNetherPortal() {
        if (!(this.level instanceof ServerLevel)) {
            return;
        }
        final int integer2 = this.getPortalWaitTime();
        if (this.isInsidePortal) {
            if (this.level.getServer().isNetherEnabled() && !this.isPassenger() && this.portalTime++ >= integer2) {
                this.level.getProfiler().push("portal");
                this.portalTime = integer2;
                this.changingDimensionDelay = this.getDimensionChangingDelay();
                this.changeDimension((this.level.dimension.getType() == DimensionType.NETHER) ? DimensionType.OVERWORLD : DimensionType.NETHER);
                this.level.getProfiler().pop();
            }
            this.isInsidePortal = false;
        }
        else {
            if (this.portalTime > 0) {
                this.portalTime -= 4;
            }
            if (this.portalTime < 0) {
                this.portalTime = 0;
            }
        }
        this.processDimensionDelay();
    }
    
    public int getDimensionChangingDelay() {
        return 300;
    }
    
    public void lerpMotion(final double double1, final double double2, final double double3) {
        this.setDeltaMovement(double1, double2, double3);
    }
    
    public void handleEntityEvent(final byte byte1) {
        switch (byte1) {
            case 53: {
                HoneyBlock.showSlideParticles(this);
                break;
            }
        }
    }
    
    public void animateHurt() {
    }
    
    public Iterable<ItemStack> getHandSlots() {
        return Entity.EMPTY_LIST;
    }
    
    public Iterable<ItemStack> getArmorSlots() {
        return Entity.EMPTY_LIST;
    }
    
    public Iterable<ItemStack> getAllSlots() {
        return Iterables.<ItemStack>concat(this.getHandSlots(), this.getArmorSlots());
    }
    
    public void setItemSlot(final EquipmentSlot akv, final ItemStack ben) {
    }
    
    public boolean isOnFire() {
        final boolean boolean2 = this.level != null && this.level.isClientSide;
        return !this.fireImmune() && (this.remainingFireTicks > 0 || (boolean2 && this.getSharedFlag(0)));
    }
    
    public boolean isPassenger() {
        return this.getVehicle() != null;
    }
    
    public boolean isVehicle() {
        return !this.getPassengers().isEmpty();
    }
    
    public boolean rideableUnderWater() {
        return true;
    }
    
    public void setShiftKeyDown(final boolean boolean1) {
        this.setSharedFlag(1, boolean1);
    }
    
    public boolean isShiftKeyDown() {
        return this.getSharedFlag(1);
    }
    
    public boolean isSteppingCarefully() {
        return this.isShiftKeyDown();
    }
    
    public boolean isSuppressingBounce() {
        return this.isShiftKeyDown();
    }
    
    public boolean isDiscrete() {
        return this.isShiftKeyDown();
    }
    
    public boolean isDescending() {
        return this.isShiftKeyDown();
    }
    
    public boolean isCrouching() {
        return this.getPose() == Pose.CROUCHING;
    }
    
    public boolean isSprinting() {
        return this.getSharedFlag(3);
    }
    
    public void setSprinting(final boolean boolean1) {
        this.setSharedFlag(3, boolean1);
    }
    
    public boolean isSwimming() {
        return this.getSharedFlag(4);
    }
    
    public boolean isVisuallySwimming() {
        return this.getPose() == Pose.SWIMMING;
    }
    
    public boolean isVisuallyCrawling() {
        return this.isVisuallySwimming() && !this.isInWater();
    }
    
    public void setSwimming(final boolean boolean1) {
        this.setSharedFlag(4, boolean1);
    }
    
    public boolean isGlowing() {
        return this.glowing || (this.level.isClientSide && this.getSharedFlag(6));
    }
    
    public void setGlowing(final boolean boolean1) {
        this.glowing = boolean1;
        if (!this.level.isClientSide) {
            this.setSharedFlag(6, this.glowing);
        }
    }
    
    public boolean isInvisible() {
        return this.getSharedFlag(5);
    }
    
    public boolean isInvisibleTo(final Player ayj) {
        if (ayj.isSpectator()) {
            return false;
        }
        final Team cwn3 = this.getTeam();
        return (cwn3 == null || ayj == null || ayj.getTeam() != cwn3 || !cwn3.canSeeFriendlyInvisibles()) && this.isInvisible();
    }
    
    @Nullable
    public Team getTeam() {
        return this.level.getScoreboard().getPlayersTeam(this.getScoreboardName());
    }
    
    public boolean isAlliedTo(final Entity akq) {
        return this.isAlliedTo(akq.getTeam());
    }
    
    public boolean isAlliedTo(final Team cwn) {
        return this.getTeam() != null && this.getTeam().isAlliedTo(cwn);
    }
    
    public void setInvisible(final boolean boolean1) {
        this.setSharedFlag(5, boolean1);
    }
    
    protected boolean getSharedFlag(final int integer) {
        return (this.entityData.<Byte>get(Entity.DATA_SHARED_FLAGS_ID) & 1 << integer) != 0x0;
    }
    
    protected void setSharedFlag(final int integer, final boolean boolean2) {
        final byte byte4 = this.entityData.<Byte>get(Entity.DATA_SHARED_FLAGS_ID);
        if (boolean2) {
            this.entityData.<Byte>set(Entity.DATA_SHARED_FLAGS_ID, (byte)(byte4 | 1 << integer));
        }
        else {
            this.entityData.<Byte>set(Entity.DATA_SHARED_FLAGS_ID, (byte)(byte4 & ~(1 << integer)));
        }
    }
    
    public int getMaxAirSupply() {
        return 300;
    }
    
    public int getAirSupply() {
        return this.entityData.<Integer>get(Entity.DATA_AIR_SUPPLY_ID);
    }
    
    public void setAirSupply(final int integer) {
        this.entityData.<Integer>set(Entity.DATA_AIR_SUPPLY_ID, integer);
    }
    
    public void thunderHit(final LightningBolt avy) {
        ++this.remainingFireTicks;
        if (this.remainingFireTicks == 0) {
            this.setSecondsOnFire(8);
        }
        this.hurt(DamageSource.LIGHTNING_BOLT, 5.0f);
    }
    
    public void onAboveBubbleCol(final boolean boolean1) {
        final Vec3 cvl3 = this.getDeltaMovement();
        double double4;
        if (boolean1) {
            double4 = Math.max(-0.9, cvl3.y - 0.03);
        }
        else {
            double4 = Math.min(1.8, cvl3.y + 0.1);
        }
        this.setDeltaMovement(cvl3.x, double4, cvl3.z);
    }
    
    public void onInsideBubbleColumn(final boolean boolean1) {
        final Vec3 cvl3 = this.getDeltaMovement();
        double double4;
        if (boolean1) {
            double4 = Math.max(-0.3, cvl3.y - 0.03);
        }
        else {
            double4 = Math.min(0.7, cvl3.y + 0.06);
        }
        this.setDeltaMovement(cvl3.x, double4, cvl3.z);
        this.fallDistance = 0.0f;
    }
    
    public void killed(final LivingEntity akz) {
    }
    
    protected void checkInBlock(final double double1, final double double2, final double double3) {
        final BlockPos fk8 = new BlockPos(double1, double2, double3);
        final Vec3 cvl9 = new Vec3(double1 - fk8.getX(), double2 - fk8.getY(), double3 - fk8.getZ());
        final BlockPos.MutableBlockPos a10 = new BlockPos.MutableBlockPos();
        Direction fp11 = Direction.UP;
        double double4 = Double.MAX_VALUE;
        for (final Direction fp12 : new Direction[] { Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST, Direction.UP }) {
            a10.set(fk8).move(fp12);
            if (!this.level.getBlockState(a10).isCollisionShapeFullBlock(this.level, a10)) {
                final double double5 = cvl9.get(fp12.getAxis());
                final double double6 = (fp12.getAxisDirection() == Direction.AxisDirection.POSITIVE) ? (1.0 - double5) : double5;
                if (double6 < double4) {
                    double4 = double6;
                    fp11 = fp12;
                }
            }
        }
        final float float14 = this.random.nextFloat() * 0.2f + 0.1f;
        final float float15 = (float)fp11.getAxisDirection().getStep();
        final Vec3 cvl10 = this.getDeltaMovement().scale(0.75);
        if (fp11.getAxis() == Direction.Axis.X) {
            this.setDeltaMovement(float15 * float14, cvl10.y, cvl10.z);
        }
        else if (fp11.getAxis() == Direction.Axis.Y) {
            this.setDeltaMovement(cvl10.x, float15 * float14, cvl10.z);
        }
        else if (fp11.getAxis() == Direction.Axis.Z) {
            this.setDeltaMovement(cvl10.x, cvl10.y, float15 * float14);
        }
    }
    
    public void makeStuckInBlock(final BlockState byj, final Vec3 cvl) {
        this.fallDistance = 0.0f;
        this.stuckSpeedMultiplier = cvl;
    }
    
    private static void removeAction(final Component lf) {
        lf.withStyle(ln -> ln.setClickEvent(null)).getSiblings().forEach(Entity::removeAction);
    }
    
    @Override
    public Component getName() {
        final Component lf2 = this.getCustomName();
        if (lf2 != null) {
            final Component lf3 = lf2.deepCopy();
            removeAction(lf3);
            return lf3;
        }
        return this.getTypeName();
    }
    
    protected Component getTypeName() {
        return this.type.getDescription();
    }
    
    public boolean is(final Entity akq) {
        return this == akq;
    }
    
    public float getYHeadRot() {
        return 0.0f;
    }
    
    public void setYHeadRot(final float float1) {
    }
    
    public void setYBodyRot(final float float1) {
    }
    
    public boolean isAttackable() {
        return true;
    }
    
    public boolean skipAttackInteraction(final Entity akq) {
        return false;
    }
    
    @Override
    public String toString() {
        return String.format(Locale.ROOT, "%s['%s'/%d, l='%s', x=%.2f, y=%.2f, z=%.2f]", this.getClass().getSimpleName(), this.getName().getContents(), this.id, (this.level == null) ? "~NULL~" : this.level.getLevelData().getLevelName(), this.getX(), this.getY(), this.getZ());
    }
    
    public boolean isInvulnerableTo(final DamageSource ajz) {
        return this.invulnerable && ajz != DamageSource.OUT_OF_WORLD && !ajz.isCreativePlayer();
    }
    
    public boolean isInvulnerable() {
        return this.invulnerable;
    }
    
    public void setInvulnerable(final boolean boolean1) {
        this.invulnerable = boolean1;
    }
    
    public void copyPosition(final Entity akq) {
        this.moveTo(akq.getX(), akq.getY(), akq.getZ(), akq.yRot, akq.xRot);
    }
    
    public void restoreFrom(final Entity akq) {
        final CompoundTag jt3 = akq.saveWithoutId(new CompoundTag());
        jt3.remove("Dimension");
        this.load(jt3);
        this.changingDimensionDelay = akq.changingDimensionDelay;
        this.portalEntranceBlock = akq.portalEntranceBlock;
        this.portalEntranceOffset = akq.portalEntranceOffset;
        this.portalEntranceForwards = akq.portalEntranceForwards;
    }
    
    @Nullable
    public Entity changeDimension(final DimensionType cbi) {
        if (this.level.isClientSide || this.removed) {
            return null;
        }
        this.level.getProfiler().push("changeDimension");
        final MinecraftServer minecraftServer3 = this.getServer();
        final DimensionType cbi2 = this.dimension;
        final ServerLevel xd5 = minecraftServer3.getLevel(cbi2);
        final ServerLevel xd6 = minecraftServer3.getLevel(cbi);
        this.dimension = cbi;
        this.unRide();
        this.level.getProfiler().push("reposition");
        Vec3 cvl8 = this.getDeltaMovement();
        float float9 = 0.0f;
        BlockPos fk7;
        if (cbi2 == DimensionType.THE_END && cbi == DimensionType.OVERWORLD) {
            fk7 = xd6.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, xd6.getSharedSpawnPos());
        }
        else if (cbi == DimensionType.THE_END) {
            fk7 = xd6.getDimensionSpecificSpawn();
        }
        else {
            double double10 = this.getX();
            double double11 = this.getZ();
            final double double12 = 8.0;
            if (cbi2 == DimensionType.OVERWORLD && cbi == DimensionType.NETHER) {
                double10 /= 8.0;
                double11 /= 8.0;
            }
            else if (cbi2 == DimensionType.NETHER && cbi == DimensionType.OVERWORLD) {
                double10 *= 8.0;
                double11 *= 8.0;
            }
            final double double13 = Math.min(-2.9999872E7, xd6.getWorldBorder().getMinX() + 16.0);
            final double double14 = Math.min(-2.9999872E7, xd6.getWorldBorder().getMinZ() + 16.0);
            final double double15 = Math.min(2.9999872E7, xd6.getWorldBorder().getMaxX() - 16.0);
            final double double16 = Math.min(2.9999872E7, xd6.getWorldBorder().getMaxZ() - 16.0);
            double10 = Mth.clamp(double10, double13, double15);
            double11 = Mth.clamp(double11, double14, double16);
            final Vec3 cvl9 = this.getPortalEntranceOffset();
            fk7 = new BlockPos(double10, this.getY(), double11);
            final BlockPattern.PortalInfo c25 = xd6.getPortalForcer().findPortal(fk7, cvl8, this.getPortalEntranceForwards(), cvl9.x, cvl9.y, this instanceof Player);
            if (c25 == null) {
                return null;
            }
            fk7 = new BlockPos(c25.pos);
            cvl8 = c25.speed;
            float9 = (float)c25.angle;
        }
        this.level.getProfiler().popPush("reloading");
        final Entity akq10 = (Entity)this.getType().create(xd6);
        if (akq10 != null) {
            akq10.restoreFrom(this);
            akq10.moveTo(fk7, akq10.yRot + float9, akq10.xRot);
            akq10.setDeltaMovement(cvl8);
            xd6.addFromAnotherDimension(akq10);
        }
        this.removed = true;
        this.level.getProfiler().pop();
        xd5.resetEmptyTime();
        xd6.resetEmptyTime();
        this.level.getProfiler().pop();
        return akq10;
    }
    
    public boolean canChangeDimensions() {
        return true;
    }
    
    public float getBlockExplosionResistance(final Explosion bjp, final BlockGetter bjg, final BlockPos fk, final BlockState byj, final FluidState coj, final float float6) {
        return float6;
    }
    
    public boolean shouldBlockExplode(final Explosion bjp, final BlockGetter bjg, final BlockPos fk, final BlockState byj, final float float5) {
        return true;
    }
    
    public int getMaxFallDistance() {
        return 3;
    }
    
    public Vec3 getPortalEntranceOffset() {
        return this.portalEntranceOffset;
    }
    
    public Direction getPortalEntranceForwards() {
        return this.portalEntranceForwards;
    }
    
    public boolean isIgnoringBlockTriggers() {
        return false;
    }
    
    public void fillCrashReportCategory(final CrashReportCategory i) {
        i.setDetail("Entity Type", () -> EntityType.getKey(this.getType()) + " (" + this.getClass().getCanonicalName() + ")");
        i.setDetail("Entity ID", this.id);
        i.setDetail("Entity Name", () -> this.getName().getString());
        i.setDetail("Entity's Exact location", String.format(Locale.ROOT, "%.2f, %.2f, %.2f", this.getX(), this.getY(), this.getZ()));
        i.setDetail("Entity's Block location", CrashReportCategory.formatLocation(Mth.floor(this.getX()), Mth.floor(this.getY()), Mth.floor(this.getZ())));
        final Vec3 cvl3 = this.getDeltaMovement();
        i.setDetail("Entity's Momentum", String.format(Locale.ROOT, "%.2f, %.2f, %.2f", cvl3.x, cvl3.y, cvl3.z));
        i.setDetail("Entity's Passengers", () -> this.getPassengers().toString());
        i.setDetail("Entity's Vehicle", () -> this.getVehicle().toString());
    }
    
    public boolean displayFireAnimation() {
        return this.isOnFire() && !this.isSpectator();
    }
    
    public void setUUID(final UUID uUID) {
        this.uuid = uUID;
        this.stringUUID = this.uuid.toString();
    }
    
    public UUID getUUID() {
        return this.uuid;
    }
    
    public String getStringUUID() {
        return this.stringUUID;
    }
    
    public String getScoreboardName() {
        return this.stringUUID;
    }
    
    public boolean isPushedByWater() {
        return true;
    }
    
    public static double getViewScale() {
        return Entity.viewScale;
    }
    
    public static void setViewScale(final double double1) {
        Entity.viewScale = double1;
    }
    
    @Override
    public Component getDisplayName() {
        return PlayerTeam.formatNameForTeam(this.getTeam(), this.getName()).withStyle(ln -> ln.setHoverEvent(this.createHoverEvent()).setInsertion(this.getStringUUID()));
    }
    
    public void setCustomName(@Nullable final Component lf) {
        this.entityData.<Optional<Component>>set(Entity.DATA_CUSTOM_NAME, Optional.<Component>ofNullable(lf));
    }
    
    @Nullable
    @Override
    public Component getCustomName() {
        return this.entityData.<Optional<Component>>get(Entity.DATA_CUSTOM_NAME).orElse(null);
    }
    
    @Override
    public boolean hasCustomName() {
        return this.entityData.<Optional<Component>>get(Entity.DATA_CUSTOM_NAME).isPresent();
    }
    
    public void setCustomNameVisible(final boolean boolean1) {
        this.entityData.<Boolean>set(Entity.DATA_CUSTOM_NAME_VISIBLE, boolean1);
    }
    
    public boolean isCustomNameVisible() {
        return this.entityData.<Boolean>get(Entity.DATA_CUSTOM_NAME_VISIBLE);
    }
    
    public final void teleportToWithTicket(final double double1, final double double2, final double double3) {
        if (!(this.level instanceof ServerLevel)) {
            return;
        }
        final ChunkPos bjh8 = new ChunkPos(new BlockPos(double1, double2, double3));
        ((ServerLevel)this.level).getChunkSource().<Integer>addRegionTicket(TicketType.POST_TELEPORT, bjh8, 0, this.getId());
        this.level.getChunk(bjh8.x, bjh8.z);
        this.teleportTo(double1, double2, double3);
    }
    
    public void teleportTo(final double double1, final double double2, final double double3) {
        if (!(this.level instanceof ServerLevel)) {
            return;
        }
        final ServerLevel xd8 = (ServerLevel)this.level;
        this.moveTo(double1, double2, double3, this.yRot, this.xRot);
        this.getSelfAndPassengers().forEach(akq -> {
            xd8.updateChunkPos(akq);
            akq.teleported = true;
            akq.repositionDirectPassengers(Entity::forceMove);
        });
    }
    
    public boolean shouldShowName() {
        return this.isCustomNameVisible();
    }
    
    public void onSyncedDataUpdated(final EntityDataAccessor<?> sb) {
        if (Entity.DATA_POSE.equals(sb)) {
            this.refreshDimensions();
        }
    }
    
    public void refreshDimensions() {
        final EntityDimensions akr2 = this.dimensions;
        final Pose alj3 = this.getPose();
        final EntityDimensions akr3 = this.getDimensions(alj3);
        this.dimensions = akr3;
        this.eyeHeight = this.getEyeHeight(alj3, akr3);
        if (akr3.width < akr2.width) {
            final double double5 = akr3.width / 2.0;
            this.setBoundingBox(new AABB(this.getX() - double5, this.getY(), this.getZ() - double5, this.getX() + double5, this.getY() + akr3.height, this.getZ() + double5));
            return;
        }
        final AABB cvf5 = this.getBoundingBox();
        this.setBoundingBox(new AABB(cvf5.minX, cvf5.minY, cvf5.minZ, cvf5.minX + akr3.width, cvf5.minY + akr3.height, cvf5.minZ + akr3.width));
        if (akr3.width > akr2.width && !this.firstTick && !this.level.isClientSide) {
            final float float6 = akr2.width - akr3.width;
            this.move(MoverType.SELF, new Vec3(float6, 0.0, float6));
        }
    }
    
    public Direction getDirection() {
        return Direction.fromYRot(this.yRot);
    }
    
    public Direction getMotionDirection() {
        return this.getDirection();
    }
    
    protected HoverEvent createHoverEvent() {
        final CompoundTag jt2 = new CompoundTag();
        final ResourceLocation sm3 = EntityType.getKey(this.getType());
        jt2.putString("id", this.getStringUUID());
        if (sm3 != null) {
            jt2.putString("type", sm3.toString());
        }
        jt2.putString("name", Component.Serializer.toJson(this.getName()));
        return new HoverEvent(HoverEvent.Action.SHOW_ENTITY, new TextComponent(jt2.toString()));
    }
    
    public boolean broadcastToPlayer(final ServerPlayer xe) {
        return true;
    }
    
    public AABB getBoundingBox() {
        return this.bb;
    }
    
    public AABB getBoundingBoxForCulling() {
        return this.getBoundingBox();
    }
    
    protected AABB getBoundingBoxForPose(final Pose alj) {
        final EntityDimensions akr3 = this.getDimensions(alj);
        final float float4 = akr3.width / 2.0f;
        final Vec3 cvl5 = new Vec3(this.getX() - float4, this.getY(), this.getZ() - float4);
        final Vec3 cvl6 = new Vec3(this.getX() + float4, this.getY() + akr3.height, this.getZ() + float4);
        return new AABB(cvl5, cvl6);
    }
    
    public void setBoundingBox(final AABB cvf) {
        this.bb = cvf;
    }
    
    protected float getEyeHeight(final Pose alj, final EntityDimensions akr) {
        return akr.height * 0.85f;
    }
    
    public float getEyeHeight(final Pose alj) {
        return this.getEyeHeight(alj, this.getDimensions(alj));
    }
    
    public final float getEyeHeight() {
        return this.eyeHeight;
    }
    
    public boolean setSlot(final int integer, final ItemStack ben) {
        return false;
    }
    
    @Override
    public void sendMessage(final Component lf) {
    }
    
    public BlockPos getCommandSenderBlockPosition() {
        return new BlockPos(this);
    }
    
    public Vec3 getCommandSenderWorldPosition() {
        return this.position();
    }
    
    public Level getCommandSenderWorld() {
        return this.level;
    }
    
    @Nullable
    public MinecraftServer getServer() {
        return this.level.getServer();
    }
    
    public InteractionResult interactAt(final Player ayj, final Vec3 cvl, final InteractionHand ajk) {
        return InteractionResult.PASS;
    }
    
    public boolean ignoreExplosion() {
        return false;
    }
    
    protected void doEnchantDamageEffects(final LivingEntity akz, final Entity akq) {
        if (akq instanceof LivingEntity) {
            EnchantmentHelper.doPostHurtEffects((LivingEntity)akq, akz);
        }
        EnchantmentHelper.doPostDamageEffects(akz, akq);
    }
    
    public void startSeenByPlayer(final ServerPlayer xe) {
    }
    
    public void stopSeenByPlayer(final ServerPlayer xe) {
    }
    
    public float rotate(final Rotation btu) {
        final float float3 = Mth.wrapDegrees(this.yRot);
        switch (btu) {
            case CLOCKWISE_180: {
                return float3 + 180.0f;
            }
            case COUNTERCLOCKWISE_90: {
                return float3 + 270.0f;
            }
            case CLOCKWISE_90: {
                return float3 + 90.0f;
            }
            default: {
                return float3;
            }
        }
    }
    
    public float mirror(final Mirror bsu) {
        final float float3 = Mth.wrapDegrees(this.yRot);
        switch (bsu) {
            case LEFT_RIGHT: {
                return -float3;
            }
            case FRONT_BACK: {
                return 180.0f - float3;
            }
            default: {
                return float3;
            }
        }
    }
    
    public boolean onlyOpCanSetNbt() {
        return false;
    }
    
    public boolean checkAndResetTeleportedFlag() {
        final boolean boolean2 = this.teleported;
        this.teleported = false;
        return boolean2;
    }
    
    @Nullable
    public Entity getControllingPassenger() {
        return null;
    }
    
    public List<Entity> getPassengers() {
        if (this.passengers.isEmpty()) {
            return Collections.<Entity>emptyList();
        }
        return Lists.newArrayList(this.passengers);
    }
    
    public boolean hasPassenger(final Entity akq) {
        for (final Entity akq2 : this.getPassengers()) {
            if (akq2.equals(akq)) {
                return true;
            }
        }
        return false;
    }
    
    public boolean hasPassenger(final Class<? extends Entity> class1) {
        for (final Entity akq4 : this.getPassengers()) {
            if (class1.isAssignableFrom(akq4.getClass())) {
                return true;
            }
        }
        return false;
    }
    
    public Collection<Entity> getIndirectPassengers() {
        final Set<Entity> set2 = Sets.newHashSet();
        for (final Entity akq4 : this.getPassengers()) {
            set2.add(akq4);
            akq4.fillIndirectPassengers(false, set2);
        }
        return set2;
    }
    
    public Stream<Entity> getSelfAndPassengers() {
        return Stream.<Entity>concat(Stream.of((T)this), this.passengers.stream().flatMap(Entity::getSelfAndPassengers));
    }
    
    public boolean hasOnePlayerPassenger() {
        final Set<Entity> set2 = Sets.newHashSet();
        this.fillIndirectPassengers(true, set2);
        return set2.size() == 1;
    }
    
    private void fillIndirectPassengers(final boolean boolean1, final Set<Entity> set) {
        for (final Entity akq5 : this.getPassengers()) {
            if (!boolean1 || ServerPlayer.class.isAssignableFrom(akq5.getClass())) {
                set.add(akq5);
            }
            akq5.fillIndirectPassengers(boolean1, set);
        }
    }
    
    public Entity getRootVehicle() {
        Entity akq2;
        for (akq2 = this; akq2.isPassenger(); akq2 = akq2.getVehicle()) {}
        return akq2;
    }
    
    public boolean isPassengerOfSameVehicle(final Entity akq) {
        return this.getRootVehicle() == akq.getRootVehicle();
    }
    
    public boolean hasIndirectPassenger(final Entity akq) {
        for (final Entity akq2 : this.getPassengers()) {
            if (akq2.equals(akq)) {
                return true;
            }
            if (akq2.hasIndirectPassenger(akq)) {
                return true;
            }
        }
        return false;
    }
    
    public void repositionDirectPassengers(final MoveCallback a) {
        for (final Entity akq4 : this.passengers) {
            this.positionRider(akq4, a);
        }
    }
    
    public boolean isControlledByLocalInstance() {
        final Entity akq2 = this.getControllingPassenger();
        if (akq2 instanceof Player) {
            return ((Player)akq2).isLocalPlayer();
        }
        return !this.level.isClientSide;
    }
    
    @Nullable
    public Entity getVehicle() {
        return this.vehicle;
    }
    
    public PushReaction getPistonPushReaction() {
        return PushReaction.NORMAL;
    }
    
    public SoundSource getSoundSource() {
        return SoundSource.NEUTRAL;
    }
    
    protected int getFireImmuneTicks() {
        return 1;
    }
    
    public CommandSourceStack createCommandSourceStack() {
        return new CommandSourceStack(this, this.position(), this.getRotationVector(), (this.level instanceof ServerLevel) ? ((ServerLevel)this.level) : null, this.getPermissionLevel(), this.getName().getString(), this.getDisplayName(), this.level.getServer(), this);
    }
    
    protected int getPermissionLevel() {
        return 0;
    }
    
    public boolean hasPermissions(final int integer) {
        return this.getPermissionLevel() >= integer;
    }
    
    @Override
    public boolean acceptsSuccess() {
        return this.level.getGameRules().getBoolean(GameRules.RULE_SENDCOMMANDFEEDBACK);
    }
    
    @Override
    public boolean acceptsFailure() {
        return true;
    }
    
    @Override
    public boolean shouldInformAdmins() {
        return true;
    }
    
    public void lookAt(final EntityAnchorArgument.Anchor a, final Vec3 cvl) {
        final Vec3 cvl2 = a.apply(this);
        final double double5 = cvl.x - cvl2.x;
        final double double6 = cvl.y - cvl2.y;
        final double double7 = cvl.z - cvl2.z;
        final double double8 = Mth.sqrt(double5 * double5 + double7 * double7);
        this.xRot = Mth.wrapDegrees((float)(-(Mth.atan2(double6, double8) * 57.2957763671875)));
        this.setYHeadRot(this.yRot = Mth.wrapDegrees((float)(Mth.atan2(double7, double5) * 57.2957763671875) - 90.0f));
        this.xRotO = this.xRot;
        this.yRotO = this.yRot;
    }
    
    public boolean checkAndHandleWater(final Tag<Fluid> aaz) {
        final AABB cvf3 = this.getBoundingBox().deflate(0.001);
        final int integer4 = Mth.floor(cvf3.minX);
        final int integer5 = Mth.ceil(cvf3.maxX);
        final int integer6 = Mth.floor(cvf3.minY);
        final int integer7 = Mth.ceil(cvf3.maxY);
        final int integer8 = Mth.floor(cvf3.minZ);
        final int integer9 = Mth.ceil(cvf3.maxZ);
        if (!this.level.hasChunksAt(integer4, integer6, integer8, integer5, integer7, integer9)) {
            return false;
        }
        double double10 = 0.0;
        final boolean boolean12 = this.isPushedByWater();
        boolean boolean13 = false;
        Vec3 cvl14 = Vec3.ZERO;
        int integer10 = 0;
        try (final BlockPos.PooledMutableBlockPos b16 = BlockPos.PooledMutableBlockPos.acquire()) {
            for (int integer11 = integer4; integer11 < integer5; ++integer11) {
                for (int integer12 = integer6; integer12 < integer7; ++integer12) {
                    for (int integer13 = integer8; integer13 < integer9; ++integer13) {
                        b16.set(integer11, integer12, integer13);
                        final FluidState coj21 = this.level.getFluidState(b16);
                        if (coj21.is(aaz)) {
                            final double double11 = integer12 + coj21.getHeight(this.level, b16);
                            if (double11 >= cvf3.minY) {
                                boolean13 = true;
                                double10 = Math.max(double11 - cvf3.minY, double10);
                                if (boolean12) {
                                    Vec3 cvl15 = coj21.getFlow(this.level, b16);
                                    if (double10 < 0.4) {
                                        cvl15 = cvl15.scale(double10);
                                    }
                                    cvl14 = cvl14.add(cvl15);
                                    ++integer10;
                                }
                            }
                        }
                    }
                }
            }
        }
        if (cvl14.length() > 0.0) {
            if (integer10 > 0) {
                cvl14 = cvl14.scale(1.0 / integer10);
            }
            if (!(this instanceof Player)) {
                cvl14 = cvl14.normalize();
            }
            this.setDeltaMovement(this.getDeltaMovement().add(cvl14.scale(0.014)));
        }
        this.waterHeight = double10;
        return boolean13;
    }
    
    public double getWaterHeight() {
        return this.waterHeight;
    }
    
    public final float getBbWidth() {
        return this.dimensions.width;
    }
    
    public final float getBbHeight() {
        return this.dimensions.height;
    }
    
    public abstract Packet<?> getAddEntityPacket();
    
    public EntityDimensions getDimensions(final Pose alj) {
        return this.type.getDimensions();
    }
    
    public Vec3 position() {
        return new Vec3(this.x, this.y, this.z);
    }
    
    public Vec3 getDeltaMovement() {
        return this.deltaMovement;
    }
    
    public void setDeltaMovement(final Vec3 cvl) {
        this.deltaMovement = cvl;
    }
    
    public void setDeltaMovement(final double double1, final double double2, final double double3) {
        this.setDeltaMovement(new Vec3(double1, double2, double3));
    }
    
    public final double getX() {
        return this.x;
    }
    
    public double getX(final double double1) {
        return this.x + this.getBbWidth() * double1;
    }
    
    public double getRandomX(final double double1) {
        return this.getX((2.0 * this.random.nextDouble() - 1.0) * double1);
    }
    
    public final double getY() {
        return this.y;
    }
    
    public double getY(final double double1) {
        return this.y + this.getBbHeight() * double1;
    }
    
    public double getRandomY() {
        return this.getY(this.random.nextDouble());
    }
    
    public double getEyeY() {
        return this.y + this.eyeHeight;
    }
    
    public final double getZ() {
        return this.z;
    }
    
    public double getZ(final double double1) {
        return this.z + this.getBbWidth() * double1;
    }
    
    public double getRandomZ(final double double1) {
        return this.getZ((2.0 * this.random.nextDouble() - 1.0) * double1);
    }
    
    public void setPosRaw(final double double1, final double double2, final double double3) {
        this.x = double1;
        this.y = double2;
        this.z = double3;
    }
    
    public void checkDespawn() {
    }
    
    public void forceMove(final double double1, final double double2, final double double3) {
        this.moveTo(double1, double2, double3, this.yRot, this.xRot);
    }
    
    static {
        LOGGER = LogManager.getLogger();
        ENTITY_COUNTER = new AtomicInteger();
        EMPTY_LIST = Collections.<ItemStack>emptyList();
        INITIAL_AABB = new AABB(0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
        Entity.viewScale = 1.0;
        DATA_SHARED_FLAGS_ID = SynchedEntityData.<Byte>defineId(Entity.class, EntityDataSerializers.BYTE);
        DATA_AIR_SUPPLY_ID = SynchedEntityData.<Integer>defineId(Entity.class, EntityDataSerializers.INT);
        DATA_CUSTOM_NAME = SynchedEntityData.<Optional<Component>>defineId(Entity.class, EntityDataSerializers.OPTIONAL_COMPONENT);
        DATA_CUSTOM_NAME_VISIBLE = SynchedEntityData.<Boolean>defineId(Entity.class, EntityDataSerializers.BOOLEAN);
        DATA_SILENT = SynchedEntityData.<Boolean>defineId(Entity.class, EntityDataSerializers.BOOLEAN);
        DATA_NO_GRAVITY = SynchedEntityData.<Boolean>defineId(Entity.class, EntityDataSerializers.BOOLEAN);
        DATA_POSE = SynchedEntityData.<Pose>defineId(Entity.class, EntityDataSerializers.POSE);
    }
    
    @FunctionalInterface
    public interface MoveCallback {
        void accept(final Entity akq, final double double2, final double double3, final double double4);
    }
}
