package dev.crucifixbeta.mod.modules.impl.combat;

import dev.crucifixbeta.CrucifixBeta;
import dev.crucifixbeta.api.events.eventbus.EventListener;
import dev.crucifixbeta.api.events.impl.ClientTickEvent;
import dev.crucifixbeta.api.utils.combat.CombatUtil;
import dev.crucifixbeta.api.utils.math.Timer;
import dev.crucifixbeta.api.utils.player.EntityUtil;
import dev.crucifixbeta.api.utils.player.InventoryUtil;
import dev.crucifixbeta.api.utils.world.BlockPosX;
import dev.crucifixbeta.api.utils.world.BlockUtil;
import dev.crucifixbeta.core.impl.CommandManager;
import dev.crucifixbeta.core.impl.RotationManager;
import dev.crucifixbeta.mod.modules.Module;
import dev.crucifixbeta.mod.modules.impl.client.AntiCheat;
import dev.crucifixbeta.mod.modules.impl.exploit.Blink;
import dev.crucifixbeta.mod.modules.impl.player.PacketMine;
import dev.crucifixbeta.mod.modules.settings.impl.BooleanSetting;
import dev.crucifixbeta.mod.modules.settings.impl.EnumSetting;
import dev.crucifixbeta.mod.modules.settings.impl.SliderSetting;
import java.util.ArrayList;
import java.util.List;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.Blocks;
import net.minecraft.entity.Entity;
import net.minecraft.entity.ExperienceOrbEntity;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.decoration.EndCrystalEntity;
import net.minecraft.entity.projectile.ArrowEntity;
import net.minecraft.entity.projectile.thrown.ExperienceBottleEntity;
import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket.LookAndOnGround;
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket.PositionAndOnGround;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;

@Environment(EnvType.CLIENT)
public class IceBurrow extends Module {
   public static IceBurrow INSTANCE;
   private final EnumSetting<IceBurrow.RotateMode> rotate = this.add(new EnumSetting<>("RotateMode", IceBurrow.RotateMode.Bypass));
   private final EnumSetting<IceBurrow.LagBackMode> lagMode = this.add(new EnumSetting<>("LagMode", IceBurrow.LagBackMode.TrollHack));
   private final EnumSetting<IceBurrow.LagBackMode> aboveLagMode = this.add(new EnumSetting<>("MoveLagMode", IceBurrow.LagBackMode.Smart));
   private final List<BlockPos> placePos = new ArrayList<>();
   private final Timer timer = new Timer();
   private final Timer webTimer = new Timer();
   private final BooleanSetting disable = this.add(new BooleanSetting("Disable", true));
   private final BooleanSetting jumpDisable = this.add(new BooleanSetting("JumpDisable", true, () -> !this.disable.getValue()));
   private final SliderSetting delay = this.add(new SliderSetting("Delay", 500, 0, 1000, () -> !this.disable.getValue()));
   private final SliderSetting webTime = this.add(new SliderSetting("WebTime", 0, 0, 500));
   private final BooleanSetting packedIce = this.add(new BooleanSetting("PackedIce", true));
   private final BooleanSetting antiLag = this.add(new BooleanSetting("AntiLag", false));
   private final BooleanSetting single = this.add(new BooleanSetting("SingleBlock", false));
   private final BooleanSetting detectMine = this.add(new BooleanSetting("DetectMining", false));
   private final BooleanSetting headFill = this.add(new BooleanSetting("HeadFill", false));
   private final BooleanSetting usingPause = this.add(new BooleanSetting("UsingPause", false));
   private final BooleanSetting down = this.add(new BooleanSetting("Down", true));
   private final BooleanSetting noSelfPos = this.add(new BooleanSetting("NoSelfPos", false));
   private final BooleanSetting packetPlace = this.add(new BooleanSetting("PacketPlace", true));
   private final BooleanSetting sound = this.add(new BooleanSetting("Sound", true));
   private final SliderSetting blocksPer = this.add(new SliderSetting("BlocksPer", 4.0, 1.0, 4.0, 1.0));
   private final BooleanSetting breakCrystal = this.add(new BooleanSetting("Break", true));
   private final BooleanSetting breakIce = this.add(new BooleanSetting("BreakIce", true));
   private final SliderSetting breakDelay = this.add(new SliderSetting("BreakDelay", 500, 0, 1000, this.breakIce::getValue));
   private final Timer breakTimer = new Timer();
   private final BooleanSetting wait = this.add(new BooleanSetting("Wait", true, this.disable::getValue));
   private final BooleanSetting fakeMove = this.add(new BooleanSetting("FakeMove", true).setParent());
   private final BooleanSetting center = this.add(new BooleanSetting("AllowCenter", true, this.fakeMove::isOpen));
   private final SliderSetting preCorrect = this.add(new SliderSetting("PreCorrect", 0.25, 0.0, 1.0, 0.001, this.fakeMove::isOpen));
   private final SliderSetting moveDis = this.add(new SliderSetting("MoveDis", 0.25, 0.0, 1.0, 0.001, this.fakeMove::isOpen));
   private final SliderSetting moveDis2 = this.add(new SliderSetting("MoveDis2", 0.25, 0.0, 1.0, 0.001, this.fakeMove::isOpen));
   private final SliderSetting moveCorrect2 = this.add(new SliderSetting("Correct", 0.25, 0.0, 1.0, 0.001, this.fakeMove::isOpen));
   private final SliderSetting yOffset = this.add(new SliderSetting("YOffset", 0.01, 0.0, 1.0, 0.001, this.fakeMove::isOpen));
   private final BooleanSetting inventory = this.add(new BooleanSetting("InventorySwap", true));
   private final SliderSetting smartX = this.add(
      new SliderSetting(
         "SmartXZ",
         3.0,
         0.0,
         10.0,
         0.1,
         () -> this.lagMode.getValue() == IceBurrow.LagBackMode.Smart || this.aboveLagMode.getValue() == IceBurrow.LagBackMode.Smart
      )
   );
   private final SliderSetting smartUp = this.add(
      new SliderSetting(
         "SmartUp",
         3.0,
         0.0,
         10.0,
         0.1,
         () -> this.lagMode.getValue() == IceBurrow.LagBackMode.Smart || this.aboveLagMode.getValue() == IceBurrow.LagBackMode.Smart
      )
   );
   private final SliderSetting smartDown = this.add(
      new SliderSetting(
         "SmartDown",
         3.0,
         0.0,
         10.0,
         0.1,
         () -> this.lagMode.getValue() == IceBurrow.LagBackMode.Smart || this.aboveLagMode.getValue() == IceBurrow.LagBackMode.Smart
      )
   );
   private final SliderSetting smartDistance = this.add(
      new SliderSetting(
         "SmartDistance",
         2.0,
         0.0,
         10.0,
         0.1,
         () -> this.lagMode.getValue() == IceBurrow.LagBackMode.Smart || this.aboveLagMode.getValue() == IceBurrow.LagBackMode.Smart
      )
   );
   private int progress = 0;
   private Vec3d currentPos;

   public IceBurrow() {
      super("IceBurrow", Module.Category.Combat);
      this.setChinese("\u51b0\u5757\u5361\u4f4d");
      INSTANCE = this;
   }

   @EventListener
   public void onUpdate(ClientTickEvent event) {
      this.breakIceBlocks();
      if (!this.inventory.getValue() || EntityUtil.inInventory()) {
         if (event.isPost()) {
            if (!this.disable.getValue() && this.jumpDisable.getValue() && mc.player.input.jumping) {
               this.disable();
               return;
            }

            if (CrucifixBeta.PLAYER.isInWeb(mc.player)) {
               this.webTimer.reset();
               return;
            }

            if (this.usingPause.getValue() && this.shouldPauseForUsingItem()) {
               return;
            }

            if (!this.webTimer.passedMs(this.webTime.getValue())) {
               return;
            }

            if (!this.disable.getValue() && !this.timer.passedMs(this.delay.getValue())) {
               return;
            }

            if (!mc.player.isOnGround()) {
               return;
            }

            if (this.antiLag.getValue() && !BlockUtil.canCollide(mc.player, new Box(EntityUtil.getPlayerPos(true).down()))) {
               return;
            }

            if (this.single.getValue() && EntityUtil.isInsideBlock()) {
               if (this.disable.getValue()) {
                  this.disable();
               }

               return;
            }

            if (Blink.INSTANCE.isOn() && Blink.INSTANCE.pauseModule.getValue()) {
               return;
            }

            int var2 = mc.player.getInventory().selectedSlot;
            int var3 = this.getBlock();
            if (var3 == -1) {
               CommandManager.sendMessageId("\u00a74No ice block found.", this.hashCode() - 1);
               this.disable();
               return;
            }

            this.progress = 0;
            this.placePos.clear();
            double var4 = this.single.getValue() ? 0.0 : AntiCheat.getOffset();
            BlockPosX var6 = new BlockPosX(mc.player.getX() + var4, mc.player.getY() + 0.5, mc.player.getZ() + var4);
            BlockPosX var7 = new BlockPosX(mc.player.getX() - var4, mc.player.getY() + 0.5, mc.player.getZ() + var4);
            BlockPosX var8 = new BlockPosX(mc.player.getX() + var4, mc.player.getY() + 0.5, mc.player.getZ() - var4);
            BlockPosX var9 = new BlockPosX(mc.player.getX() - var4, mc.player.getY() + 0.5, mc.player.getZ() - var4);
            BlockPosX var10 = new BlockPosX(mc.player.getX() + var4, mc.player.getY() + 1.5, mc.player.getZ() + var4);
            BlockPosX var11 = new BlockPosX(mc.player.getX() - var4, mc.player.getY() + 1.5, mc.player.getZ() + var4);
            BlockPosX var12 = new BlockPosX(mc.player.getX() + var4, mc.player.getY() + 1.5, mc.player.getZ() - var4);
            BlockPosX var13 = new BlockPosX(mc.player.getX() - var4, mc.player.getY() + 1.5, mc.player.getZ() - var4);
            BlockPosX var14 = new BlockPosX(mc.player.getX() + var4, mc.player.getY() - 1.0, mc.player.getZ() + var4);
            BlockPosX var15 = new BlockPosX(mc.player.getX() - var4, mc.player.getY() - 1.0, mc.player.getZ() + var4);
            BlockPosX var16 = new BlockPosX(mc.player.getX() + var4, mc.player.getY() - 1.0, mc.player.getZ() - var4);
            BlockPosX var17 = new BlockPosX(mc.player.getX() - var4, mc.player.getY() - 1.0, mc.player.getZ() - var4);
            BlockPos var18 = EntityUtil.getPlayerPos(true);
            boolean var19 = false;
            if (!this.canPlace(var6) && !this.canPlace(var7) && !this.canPlace(var8) && !this.canPlace(var9)) {
               boolean var20 = !this.headFill.getValue() || !this.canPlace(var10) && !this.canPlace(var11) && !this.canPlace(var12) && !this.canPlace(var13);
               boolean var21 = !this.down.getValue() || !this.canPlace(var14) && !this.canPlace(var15) && !this.canPlace(var16) && !this.canPlace(var17);
               if (var20) {
                  if (var21) {
                     if (!this.wait.getValue() && this.disable.getValue()) {
                        this.disable();
                     }

                     return;
                  }
               } else {
                  var19 = true;
               }
            }

            boolean var34 = false;
            BlockPos var33 = EntityUtil.getPlayerPos(true).up(2);
            boolean var22 = this.rotate.getValue() == IceBurrow.RotateMode.Normal;
            CombatUtil.attackCrystal(var6, var22, false);
            CombatUtil.attackCrystal(var7, var22, false);
            CombatUtil.attackCrystal(var8, var22, false);
            CombatUtil.attackCrystal(var9, var22, false);
            if (!var19
               && !mc.player.isCrawling()
               && !this.trapped(var33)
               && !this.trapped(var33.add(1, 0, 0))
               && !this.trapped(var33.add(-1, 0, 0))
               && !this.trapped(var33.add(0, 0, 1))
               && !this.trapped(var33.add(0, 0, -1))
               && !this.trapped(var33.add(1, 0, -1))
               && !this.trapped(var33.add(-1, 0, -1))
               && !this.trapped(var33.add(1, 0, 1))
               && !this.trapped(var33.add(-1, 0, 1))) {
               mc.getNetworkHandler().sendPacket(new PositionAndOnGround(mc.player.getX(), mc.player.getY() + 0.4199999868869781, mc.player.getZ(), false));
               mc.getNetworkHandler().sendPacket(new PositionAndOnGround(mc.player.getX(), mc.player.getY() + 0.7531999805212017, mc.player.getZ(), false));
               mc.getNetworkHandler().sendPacket(new PositionAndOnGround(mc.player.getX(), mc.player.getY() + 0.9999957640154541, mc.player.getZ(), false));
               mc.getNetworkHandler().sendPacket(new PositionAndOnGround(mc.player.getX(), mc.player.getY() + 1.1661092609382138, mc.player.getZ(), false));
               this.currentPos = new Vec3d(mc.player.getX(), mc.player.getY() + 1.1661092609382138, mc.player.getZ());
            } else {
               var34 = true;
               if (!this.fakeMove.getValue()) {
                  if (!this.wait.getValue() && this.disable.getValue()) {
                     this.disable();
                  }

                  return;
               }

               if (!this.fakeMove()) {
                  return;
               }
            }

            this.timer.reset();
            this.doSwap(var3);
            if (this.rotate.getValue() == IceBurrow.RotateMode.Bypass) {
               if (var34) {
                  float[] var23 = RotationManager.getRotation(
                     this.currentPos.add(0.0, (double)mc.player.getEyeHeight(mc.player.getPose()), 0.0), mc.player.getPos()
                  );
                  CrucifixBeta.ROTATION.snapAt(var23[0], var23[1]);
               } else {
                  CrucifixBeta.ROTATION.snapAt(CrucifixBeta.ROTATION.rotationYaw, 90.0F);
               }
            }

            this.placeBlock(var18, var22);
            this.placeBlock(var6, var22);
            this.placeBlock(var7, var22);
            this.placeBlock(var8, var22);
            this.placeBlock(var9, var22);
            if (this.down.getValue()) {
               this.placeBlock(var14, var22);
               this.placeBlock(var15, var22);
               this.placeBlock(var16, var22);
               this.placeBlock(var17, var22);
            }

            if (this.headFill.getValue() && var34) {
               this.placeBlock(var10, var22);
               this.placeBlock(var11, var22);
               this.placeBlock(var12, var22);
               this.placeBlock(var13, var22);
            }

            if (this.inventory.getValue()) {
               this.doSwap(var3);
               EntityUtil.syncInventory();
            } else {
               this.doSwap(var2);
            }

            switch (var34 ? (IceBurrow.LagBackMode)this.aboveLagMode.getValue() : (IceBurrow.LagBackMode)this.lagMode.getValue()) {
               case Smart:
                   ArrayList<BlockPos> var36 = new ArrayList<>();

                  for (double var24 = mc.player.getPos().getX() - this.smartX.getValue(); var24 < mc.player.getPos().getX() + this.smartX.getValue(); var24++) {
                     for (double var26 = mc.player.getPos().getZ() - this.smartX.getValue();
                        var26 < mc.player.getPos().getZ() + this.smartX.getValue();
                        var26++
                     ) {
                        for (double var28 = mc.player.getPos().getY() - this.smartDown.getValue();
                           var28 < mc.player.getPos().getY() + this.smartUp.getValue();
                           var28++
                        ) {
                           var36.add(new BlockPosX(var24, var28, var26));
                        }
                     }
                  }

                  double var37 = 0.0;
                  BlockPos var30 = null;

                  for (BlockPos var32 : var36) {
                     if (this.canMove(var32)
                        && !(
                           (double)MathHelper.sqrt((float)mc.player.squaredDistanceTo(var32.toCenterPos().add(0.0, -0.5, 0.0))) < this.smartDistance.getValue()
                        )
                        && (var30 == null || mc.player.squaredDistanceTo(var32.toCenterPos()) < var37)) {
                        var30 = var32;
                        var37 = mc.player.squaredDistanceTo(var32.toCenterPos());
                     }
                  }

                  if (var30 != null) {
                     mc.getNetworkHandler()
                        .sendPacket(new PositionAndOnGround((double)var30.getX() + 0.5, (double)var30.getY(), (double)var30.getZ() + 0.5, false));
                  }
                  break;
               case Invalid:
                  for (int var35 = 0; var35 < 20; var35++) {
                     mc.getNetworkHandler().sendPacket(new PositionAndOnGround(mc.player.getX(), mc.player.getY() + 1337.0, mc.player.getZ(), false));
                  }
                  break;
               case TrollHack:
                  mc.getNetworkHandler().sendPacket(new PositionAndOnGround(mc.player.getX(), mc.player.getY() + 2.3400880035762786, mc.player.getZ(), false));
                  break;
               case ToVoid:
                  mc.getNetworkHandler().sendPacket(new PositionAndOnGround(mc.player.getX(), -70.0, mc.player.getZ(), false));
                  break;
               case ToVoid2:
                  mc.getNetworkHandler().sendPacket(new PositionAndOnGround(mc.player.getX(), -7.0, mc.player.getZ(), false));
                  break;
               case Normal:
                  mc.getNetworkHandler().sendPacket(new PositionAndOnGround(mc.player.getX(), mc.player.getY() + 1.9, mc.player.getZ(), false));
                  break;
               case Rotation:
                  mc.getNetworkHandler().sendPacket(new LookAndOnGround(-180.0F, -90.0F, false));
                  mc.getNetworkHandler().sendPacket(new LookAndOnGround(180.0F, 90.0F, false));
                  break;
               case Fly:
                  mc.getNetworkHandler().sendPacket(new PositionAndOnGround(mc.player.getX(), mc.player.getY() + 1.16610926093821, mc.player.getZ(), false));
                  mc.getNetworkHandler().sendPacket(new PositionAndOnGround(mc.player.getX(), mc.player.getY() + 1.170005801788139, mc.player.getZ(), false));
                  mc.getNetworkHandler().sendPacket(new PositionAndOnGround(mc.player.getX(), mc.player.getY() + 1.2426308013947485, mc.player.getZ(), false));
                  mc.getNetworkHandler().sendPacket(new PositionAndOnGround(mc.player.getX(), mc.player.getY() + 2.3400880035762786, mc.player.getZ(), false));
                  mc.getNetworkHandler().sendPacket(new PositionAndOnGround(mc.player.getX(), mc.player.getY() + 2.640088003576279, mc.player.getZ(), false));
                  break;
               case Glide:
                  mc.getNetworkHandler().sendPacket(new PositionAndOnGround(mc.player.getX(), mc.player.getY() + 1.1001, mc.player.getZ(), false));
                  mc.getNetworkHandler().sendPacket(new PositionAndOnGround(mc.player.getX(), mc.player.getY() + 1.0605, mc.player.getZ(), false));
                  mc.getNetworkHandler().sendPacket(new PositionAndOnGround(mc.player.getX(), mc.player.getY() + 1.0802, mc.player.getZ(), false));
                  mc.getNetworkHandler().sendPacket(new PositionAndOnGround(mc.player.getX(), mc.player.getY() + 1.1127, mc.player.getZ(), false));
            }

            if (this.disable.getValue()) {
               this.disable();
            }
         }
      }
   }

   private boolean fakeMove() {
      double[] var1 = new double[]{1.0, 0.0, -1.0};
      ArrayList<BlockPos> var2 = new ArrayList<>();
      BlockPos var3 = mc.player.getBlockPos();

      for (double var7 : var1) {
         for (double var12 : var1) {
            var2.add(new BlockPosX(mc.player.getX() + var7, mc.player.getY(), mc.player.getZ() + var12));
         }
      }

      for (BlockPos var21 : var2) {
         if (this.checkSelf(var21) && !BlockUtil.canReplace(var21) && (!this.headFill.getValue() || !BlockUtil.canReplace(var21.up()))) {
            this.gotoPos(var21);
            return true;
         }
      }

      ArrayList<BlockPos> var22 = new ArrayList<>();

      for (BlockPos var14 : var2) {
         if (!var3.equals(var14) && this.checkSelf(var14) && this.canMove(var14)) {
            var22.add(var14);
         }
      }

      if (!var22.isEmpty()) {
         double var32 = 10.0;
         BlockPos var33 = null;

         for (BlockPos var29 : var22) {
            double var34 = mc.player.getPos().distanceTo(var29.toCenterPos().add(0.0, -0.5, 0.0));
            if (var34 < var32 || var33 == null) {
               var33 = var29;
               var32 = var34;
            }
         }

         this.gotoPos(var33);
         return true;
      } else {
         for (BlockPos var30 : var2) {
            if (!var3.equals(var30) && this.checkSelf(var30)) {
               var22.add(var30);
            }
         }

         if (!var22.isEmpty()) {
            double var15 = 10.0;
            BlockPos var17 = null;

            for (BlockPos var28 : var22) {
               double var18 = mc.player.getPos().distanceTo(var28.toCenterPos().add(0.0, -0.5, 0.0));
               if (var18 < var15 || var17 == null) {
                  var17 = var28;
                  var15 = var18;
               }
            }

            this.gotoPos(var17);
            return true;
         } else if (!this.center.getValue()) {
            return false;
         } else {
            var2.clear();
            var2.add(new BlockPosX(mc.player.getX() + 1.0, mc.player.getY(), mc.player.getZ()));
            var2.add(new BlockPosX(mc.player.getX() - 1.0, mc.player.getY(), mc.player.getZ()));
            var2.add(new BlockPosX(mc.player.getX(), mc.player.getY(), mc.player.getZ() - 1.0));
            var2.add(new BlockPosX(mc.player.getX(), mc.player.getY(), mc.player.getZ() + 1.0));

            for (BlockPos var31 : var2) {
               if (this.canMove(var31)) {
                  this.gotoPos(var31);
                  return true;
               }
            }

            if (!this.wait.getValue() && this.disable.getValue()) {
               this.disable();
            }

            return false;
         }
      }
   }

   private void placeBlock(BlockPos pos, boolean rotate) {
      if (this.canPlace(pos) && !this.placePos.contains(pos) && this.progress < this.blocksPer.getValueInt()) {
         this.placePos.add(pos);
         if (BlockUtil.allowAirPlace()) {
            this.progress++;
            BlockUtil.placedPos.add(pos);
            if (this.sound.getValue()) {
               mc.world.playSound(mc.player, pos, SoundEvents.BLOCK_GLASS_PLACE, SoundCategory.BLOCKS, 1.0F, 0.8F);
            }

            this.clickBlock(pos, Direction.DOWN, rotate, Hand.MAIN_HAND, this.packetPlace.getValue());
         }

         Direction var3;
         if ((var3 = BlockUtil.getPlaceSide(pos)) == null) {
            return;
         }

         this.progress++;
         BlockUtil.placedPos.add(pos);
         this.breakTimer.reset();
         if (this.sound.getValue()) {
            mc.world.playSound(mc.player, pos, SoundEvents.BLOCK_GLASS_PLACE, SoundCategory.BLOCKS, 1.0F, 0.8F);
         }

         this.clickBlock(pos.offset(var3), var3.getOpposite(), rotate, Hand.MAIN_HAND, this.packetPlace.getValue());
      }
   }

   public void clickBlock(BlockPos pos, Direction side, boolean rotate, Hand hand, boolean packet) {
      Vec3d var6 = new Vec3d(
         (double)pos.getX() + 0.5 + (double)side.getVector().getX() * 0.5,
         (double)pos.getY() + 0.5 + (double)side.getVector().getY() * 0.5,
         (double)pos.getZ() + 0.5 + (double)side.getVector().getZ() * 0.5
      );
      if (rotate) {
         float[] var7 = RotationManager.getRotation(this.currentPos.add(0.0, (double)mc.player.getEyeHeight(mc.player.getPose()), 0.0), var6);
         CrucifixBeta.ROTATION.snapAt(var7[0], var7[1]);
      }

      EntityUtil.swingHand(hand, AntiCheat.INSTANCE.interactSwing.getValue());
      BlockHitResult var8 = new BlockHitResult(var6, side, pos, false);
      if (packet) {
         Module.sendSequencedPacket(id -> new PlayerInteractBlockC2SPacket(hand, var8, id));
      } else {
         mc.interactionManager.interactBlock(mc.player, hand, var8);
      }

      if (rotate) {
         CrucifixBeta.ROTATION.snapBack();
      }
   }

   private void doSwap(int slot) {
      if (this.inventory.getValue()) {
         InventoryUtil.inventorySwap(slot, mc.player.getInventory().selectedSlot);
      } else {
         InventoryUtil.switchToSlot(slot);
      }
   }

   private void gotoPos(BlockPos offPos) {
      double var2 = (double)offPos.getX() + 0.5;
      double var4 = (double)offPos.getZ() + 0.5;
      double var6 = mc.player.getX();
      double var8 = mc.player.getZ();
      double var10 = mc.player.getY() + this.yOffset.getValue();
      double var12 = Math.abs(var6 - var2);
      double var14 = Math.abs(var8 - var4);
      double var16 = this.preCorrect.getValue();
      if (var16 > 0.0) {
         if (var12 >= var16) {
            double var18;
            double var19;
            var6 = var6 > var2 ? (var18 = var6 - var16) : (var19 = var6 + var16);
            mc.player.networkHandler.sendPacket(new PositionAndOnGround(var6, var10, var8, false));
         }

         if (var14 >= var16) {
            double var26;
            double var27;
            var8 = var8 > var4 ? (var26 = var8 - var16) : (var27 = var8 + var16);
            mc.player.networkHandler.sendPacket(new PositionAndOnGround(var6, var10, var8, false));
         }
      }

      var12 = Math.abs(var6 - var2);
      var14 = Math.abs(var8 - var4);
      var16 = this.moveDis.getValue();
      if (var16 > 0.0) {
         while (var12 > var16) {
            double var20;
            double var21;
            var6 = var6 > var2 ? (var20 = var6 - var16) : (var21 = var6 + var16);
            mc.player.networkHandler.sendPacket(new PositionAndOnGround(var6, var10, var8, false));
            var12 = Math.abs(var6 - var2);
         }

         while (var14 > var16) {
            double var28;
            double var29;
            var8 = var8 > var4 ? (var28 = var8 - var16) : (var29 = var8 + var16);
            mc.player.networkHandler.sendPacket(new PositionAndOnGround(var6, var10, var8, false));
            var14 = Math.abs(var8 - var4);
         }
      }

      if ((var16 = this.moveDis2.getValue()) > 0.0) {
         while (var12 > var16) {
            double var22;
            double var23;
            var6 = var6 > var2 ? (var22 = var6 - var16) : (var23 = var6 + var16);
            mc.player.networkHandler.sendPacket(new PositionAndOnGround(var6, var10, var8, false));
            var12 = Math.abs(var6 - var2);
         }

         while (var14 > var16) {
            double var30;
            double var31;
            var8 = var8 > var4 ? (var30 = var8 - var16) : (var31 = var8 + var16);
            mc.player.networkHandler.sendPacket(new PositionAndOnGround(var6, var10, var8, false));
            var14 = Math.abs(var8 - var4);
         }
      }

      if ((var16 = this.moveCorrect2.getValue()) > 0.0) {
         if (var12 >= var16) {
            double var24;
            double var25;
            var6 = var6 > var2 ? (var24 = var6 - var16) : (var25 = var6 + var16);
            mc.player.networkHandler.sendPacket(new PositionAndOnGround(var6, var10, var8, false));
         }

         if (var14 >= var16) {
            double var32;
            double var33;
            var8 = var8 > var4 ? (var32 = var8 - var16) : (var33 = var8 + var16);
            mc.player.networkHandler.sendPacket(new PositionAndOnGround(var6, var10, var8, false));
         }
      }

      this.currentPos = new Vec3d(var6, var10, var8);
   }

   private boolean canMove(BlockPos pos) {
      return mc.world.isAir(pos) && mc.world.isAir(pos.up());
   }

   private boolean canPlace(BlockPos pos) {
      if (this.noSelfPos.getValue() && pos.equals(EntityUtil.getPlayerPos(true))) {
         return false;
      } else if (!BlockUtil.allowAirPlace() && BlockUtil.getPlaceSide(pos) == null) {
         return false;
      } else if (!BlockUtil.canReplace(pos)) {
         return false;
      } else {
         return this.detectMine.getValue() && CrucifixBeta.BREAK.isMining(pos) ? false : !this.hasEntity(pos);
      }
   }

   private boolean hasEntity(BlockPos pos) {
      for (Entity var3 : BlockUtil.getEntities(new Box(pos))) {
         if (var3 != mc.player
            && var3.isAlive()
            && !(var3 instanceof ItemEntity)
            && !(var3 instanceof ExperienceOrbEntity)
            && !(var3 instanceof ExperienceBottleEntity)
            && !(var3 instanceof ArrowEntity)
            && (!(var3 instanceof EndCrystalEntity) || !this.breakCrystal.getValue())) {
            return true;
         }
      }

      return false;
   }

   private boolean checkSelf(BlockPos pos) {
      return mc.player.getBoundingBox().intersects(new Box(pos));
   }

   private boolean trapped(BlockPos pos) {
      return (BlockUtil.canCollide(mc.player, new Box(pos)) || BlockUtil.getBlock(pos) == Blocks.COBWEB) && this.checkSelf(pos.down(2));
   }

   private int getBlock() {
      if (this.inventory.getValue()) {
         return InventoryUtil.findBlockInventorySlot(Blocks.ICE) == -1 && this.packedIce.getValue()
            ? InventoryUtil.findBlockInventorySlot(Blocks.PACKED_ICE)
            : InventoryUtil.findBlockInventorySlot(Blocks.ICE);
      } else {
         return InventoryUtil.findBlock(Blocks.ICE) == -1 && this.packedIce.getValue()
            ? InventoryUtil.findBlock(Blocks.PACKED_ICE)
            : InventoryUtil.findBlock(Blocks.ICE);
      }
   }

   private void breakIceBlocks() {
      if (this.breakIce.getValue()) {
         if (this.breakTimer.passedMs(this.breakDelay.getValue())) {
            for (BlockPos var2 : this.placePos) {
               if (mc.world.getBlockState(var2).getBlock() == Blocks.ICE || mc.world.getBlockState(var2).getBlock() == Blocks.PACKED_ICE) {
                  PacketMine.INSTANCE.mine(var2);
                  this.breakTimer.reset();
                  return;
               }
            }
         }
      }
   }
@Environment(EnvType.CLIENT)
   private static enum LagBackMode {
      Smart,
      Invalid,
      TrollHack,
      ToVoid,
      ToVoid2,
      Normal,
      Rotation,
      Fly,
      Glide;

}

   @Environment(EnvType.CLIENT)
   private static enum RotateMode {
      Bypass,
      Normal,
      None;

}
}
