/*
 * Decompiled with CFR 0.152.
 * 
 * Could not load the following classes:
 *  com.llamalad7.mixinextras.injector.ModifyExpressionValue
 *  com.llamalad7.mixinextras.injector.ModifyReturnValue
 *  com.llamalad7.mixinextras.injector.v2.WrapWithCondition
 *  com.llamalad7.mixinextras.sugar.Local
 *  com.mojang.authlib.GameProfile
 *  meteordevelopment.orbit.ICancellable
 *  net.minecraft.class_10185
 *  net.minecraft.class_1297
 *  net.minecraft.class_1316
 *  net.minecraft.class_239
 *  net.minecraft.class_239$class_240
 *  net.minecraft.class_3966
 *  net.minecraft.class_437
 *  net.minecraft.class_638
 *  net.minecraft.class_742
 *  net.minecraft.class_744
 *  net.minecraft.class_746
 *  org.spongepowered.asm.mixin.Mixin
 *  org.spongepowered.asm.mixin.Shadow
 *  org.spongepowered.asm.mixin.injection.At
 *  org.spongepowered.asm.mixin.injection.At$Shift
 *  org.spongepowered.asm.mixin.injection.Inject
 *  org.spongepowered.asm.mixin.injection.callback.CallbackInfo
 *  org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable
 */
package meteordevelopment.meteorclient.mixin;

import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import com.llamalad7.mixinextras.sugar.Local;
import com.mojang.authlib.GameProfile;
import meteordevelopment.meteorclient.MeteorClient;
import meteordevelopment.meteorclient.events.entity.DropItemsEvent;
import meteordevelopment.meteorclient.events.entity.player.PlayerTickMovementEvent;
import meteordevelopment.meteorclient.events.entity.player.SendMovementPacketsEvent;
import meteordevelopment.meteorclient.systems.modules.Modules;
import meteordevelopment.meteorclient.systems.modules.movement.EntityControl;
import meteordevelopment.meteorclient.systems.modules.movement.Flight;
import meteordevelopment.meteorclient.systems.modules.movement.NoSlow;
import meteordevelopment.meteorclient.systems.modules.movement.Scaffold;
import meteordevelopment.meteorclient.systems.modules.movement.Sneak;
import meteordevelopment.meteorclient.systems.modules.movement.Sprint;
import meteordevelopment.meteorclient.systems.modules.movement.Velocity;
import meteordevelopment.meteorclient.systems.modules.player.LiquidInteract;
import meteordevelopment.meteorclient.systems.modules.player.NoMiningTrace;
import meteordevelopment.meteorclient.systems.modules.player.Portals;
import meteordevelopment.meteorclient.utils.entity.fakeplayer.FakePlayerEntity;
import meteordevelopment.orbit.ICancellable;
import net.minecraft.class_10185;
import net.minecraft.class_1297;
import net.minecraft.class_1316;
import net.minecraft.class_239;
import net.minecraft.class_3966;
import net.minecraft.class_437;
import net.minecraft.class_638;
import net.minecraft.class_742;
import net.minecraft.class_744;
import net.minecraft.class_746;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(value={class_746.class})
public abstract class ClientPlayerEntityMixin
extends class_742 {
    @Shadow
    public class_744 field_3913;

    public ClientPlayerEntityMixin(class_638 world, GameProfile profile) {
        super(world, profile);
    }

    @Inject(method={"method_7290"}, at={@At(value="HEAD")}, cancellable=true)
    private void onDropSelectedItem(boolean dropEntireStack, CallbackInfoReturnable<Boolean> info) {
        if (((DropItemsEvent)MeteorClient.EVENT_BUS.post((ICancellable)DropItemsEvent.get(this.method_6047()))).isCancelled()) {
            info.setReturnValue((Object)false);
        }
    }

    @ModifyExpressionValue(method={"method_60887"}, at={@At(value="FIELD", target="Lnet/minecraft/class_310;field_1755:Lnet/minecraft/class_437;", opcode=180)})
    private class_437 modifyNauseaCurrentScreen(class_437 original) {
        if (Modules.get().isActive(Portals.class)) {
            return null;
        }
        return original;
    }

    @ModifyExpressionValue(method={"method_67270"}, at={@At(value="INVOKE", target="Lnet/minecraft/class_746;method_6115()Z")})
    private boolean redirectUsingItem(boolean isUsingItem) {
        if (Modules.get().get(NoSlow.class).items()) {
            return false;
        }
        return isUsingItem;
    }

    @Inject(method={"method_5715"}, at={@At(value="HEAD")}, cancellable=true)
    private void onIsSneaking(CallbackInfoReturnable<Boolean> info) {
        if (Modules.get().get(Scaffold.class).scaffolding()) {
            info.setReturnValue((Object)false);
        }
        if (Modules.get().get(Flight.class).noSneak()) {
            info.setReturnValue((Object)false);
        }
    }

    @Inject(method={"method_20303"}, at={@At(value="HEAD")}, cancellable=true)
    private void onShouldSlowDown(CallbackInfoReturnable<Boolean> info) {
        if (Modules.get().get(NoSlow.class).sneaking()) {
            info.setReturnValue((Object)this.method_20448());
        }
    }

    @Inject(method={"method_30673"}, at={@At(value="HEAD")}, cancellable=true)
    private void onPushOutOfBlocks(double x, double d, CallbackInfo info) {
        Velocity velocity = Modules.get().get(Velocity.class);
        if (velocity.isActive() && velocity.blocks.get().booleanValue()) {
            info.cancel();
        }
    }

    @ModifyExpressionValue(method={"method_5773"}, at={@At(value="FIELD", target="Lnet/minecraft/class_744;field_54155:Lnet/minecraft/class_10185;", opcode=180)})
    private class_10185 isSneaking(class_10185 original) {
        if (Modules.get().get(Sneak.class).doPacket() || Modules.get().get(NoSlow.class).airStrict()) {
            return new class_10185(original.comp_3159(), original.comp_3160(), original.comp_3161(), original.comp_3162(), original.comp_3163(), true, original.comp_3165());
        }
        return original;
    }

    @Inject(method={"method_6007"}, at={@At(value="HEAD")})
    private void preTickMovement(CallbackInfo ci) {
        MeteorClient.EVENT_BUS.post((Object)PlayerTickMovementEvent.get());
    }

    @ModifyReturnValue(method={"method_3151"}, at={@At(value="RETURN")})
    private float modifyMountJumpStrength(float original) {
        if (Modules.get().get(EntityControl.class).maxJump()) {
            return 1.0f;
        }
        return original;
    }

    @Inject(method={"method_45773"}, at={@At(value="RETURN")}, cancellable=true)
    private void changeJumpingMount(CallbackInfoReturnable<class_1316> info) {
        if (Modules.get().get(EntityControl.class).cancelJump()) {
            info.setReturnValue(null);
        }
    }

    @ModifyReturnValue(method={"method_76763(Lnet/minecraft/class_1297;DDF)Lnet/minecraft/class_239;"}, at={@At(value="RETURN")})
    private static class_239 onUpdateTargetedEntity(class_239 original, @Local class_239 hitResult) {
        if (original instanceof class_3966) {
            class_3966 ehr = (class_3966)original;
            if (Modules.get().get(NoMiningTrace.class).canWork(ehr.method_17782()) && hitResult.method_17783() == class_239.class_240.field_1332) {
                return hitResult;
            }
            class_1297 class_12972 = ehr.method_17782();
            if (class_12972 instanceof FakePlayerEntity) {
                FakePlayerEntity fakePlayer = (FakePlayerEntity)class_12972;
                if (fakePlayer.noHit) {
                    return hitResult;
                }
            }
        }
        return original;
    }

    @ModifyExpressionValue(method={"method_76763(Lnet/minecraft/class_1297;DDF)Lnet/minecraft/class_239;"}, at={@At(value="INVOKE", target="Lnet/minecraft/class_1297;method_5745(DFZ)Lnet/minecraft/class_239;")})
    private static class_239 modifyRaycastResult(class_239 original, class_1297 entity, double blockInteractionRange, double entityInteractionRange, float tickProgress, @Local(ordinal=0, argsOnly=true) double maxDistance) {
        if (!Modules.get().isActive(LiquidInteract.class)) {
            return original;
        }
        if (original.method_17783() != class_239.class_240.field_1333) {
            return original;
        }
        return entity.method_5745(maxDistance, tickProgress, true);
    }

    @ModifyExpressionValue(method={"method_48300"}, at={@At(value="INVOKE", target="Lnet/minecraft/class_744;method_20622()Z")})
    private boolean modifyIsWalking(boolean original) {
        if (!Modules.get().get(Sprint.class).rageSprint()) {
            return original;
        }
        float forwards = Math.abs(this.field_6250);
        float sideways = Math.abs(this.field_6212);
        return this.method_5869() ? forwards > 1.0E-5f || sideways > 1.0E-5f : (double)forwards > 0.8 || (double)sideways > 0.8;
    }

    @ModifyExpressionValue(method={"method_6007"}, at={@At(value="INVOKE", target="Lnet/minecraft/class_744;method_20622()Z")})
    private boolean modifyMovement(boolean original) {
        if (!Modules.get().get(Sprint.class).rageSprint()) {
            return original;
        }
        return Math.abs(this.field_6212) > 1.0E-5f || Math.abs(this.field_6250) > 1.0E-5f;
    }

    @WrapWithCondition(method={"method_6007"}, at={@At(value="INVOKE", target="Lnet/minecraft/class_746;method_5728(Z)V", ordinal=3)})
    private boolean wrapSetSprinting(class_746 instance, boolean b) {
        Sprint s = Modules.get().get(Sprint.class);
        return !s.rageSprint() || s.unsprintInWater() && this.method_5799();
    }

    @Inject(method={"method_3136"}, at={@At(value="HEAD")})
    private void onSendMovementPacketsHead(CallbackInfo info) {
        MeteorClient.EVENT_BUS.post((Object)SendMovementPacketsEvent.Pre.get());
    }

    @Inject(method={"method_5773"}, at={@At(value="INVOKE", target="Lnet/minecraft/class_634;method_52787(Lnet/minecraft/class_2596;)V", ordinal=1)})
    private void onTickHasVehicleBeforeSendPackets(CallbackInfo info) {
        MeteorClient.EVENT_BUS.post((Object)SendMovementPacketsEvent.Pre.get());
    }

    @Inject(method={"method_3136"}, at={@At(value="TAIL")})
    private void onSendMovementPacketsTail(CallbackInfo info) {
        MeteorClient.EVENT_BUS.post((Object)SendMovementPacketsEvent.Post.get());
    }

    @Inject(method={"method_5773"}, at={@At(value="INVOKE", target="Lnet/minecraft/class_634;method_52787(Lnet/minecraft/class_2596;)V", ordinal=1, shift=At.Shift.AFTER)})
    private void onTickHasVehicleAfterSendPackets(CallbackInfo info) {
        MeteorClient.EVENT_BUS.post((Object)SendMovementPacketsEvent.Post.get());
    }
}

