Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Часть функционала Rotation Hitbox Base Rockstar 2.0

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
10 Авг 2025
Сообщения
14
Реакции
0
Выберите загрузчик игры
  1. Fabric
Всем привет, решил сделать снап хитбоксы под базу рокстара
В кратце эт не снапы а хиты с норм ротацией под фт, это не перенсос с система! ГПТ код имееться
Пожалуйста, авторизуйтесь для просмотра ссылки.

Java:
Expand Collapse Copy
package moscow.holly.systems.modules.modules.combat;

import com.mojang.blaze3d.systems.RenderSystem;
import moscow.holly.systems.event.EventListener;
import moscow.holly.systems.event.impl.game.AttackEvent;
import moscow.holly.systems.event.impl.player.ClientPlayerTickEvent;
import moscow.holly.systems.event.impl.render.Render3DEvent;
import moscow.holly.systems.modules.api.ModuleCategory;
import moscow.holly.systems.modules.api.ModuleInfo;
import moscow.holly.systems.modules.impl.BaseModule;
import moscow.holly.systems.setting.settings.BooleanSetting;
import moscow.holly.systems.setting.settings.ColorSetting;
import moscow.holly.systems.setting.settings.SelectSetting;
import moscow.holly.systems.setting.settings.SliderSetting;
import moscow.holly.Holly;
import moscow.holly.systems.modules.modules.combat.Aura;
import moscow.holly.utility.colors.ColorRGBA;
import moscow.holly.utility.combat.aura.TargetFinder;
import moscow.holly.utility.rotations.MoveCorrection;
import moscow.holly.utility.rotations.Rotation;
import moscow.holly.utility.rotations.RotationPriority;
import net.minecraft.client.gl.ShaderProgramKeys;
import net.minecraft.client.render.*;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
import org.joml.Matrix4f;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

@ModuleInfo(name = "Rotating Hitbox", category = ModuleCategory.COMBAT, desc = "Увеличенный хитбокс с ротацией как в Aura-Funtime")
public class RotatingHitbox extends BaseModule {
    
    private static class PerlinNoise {
        private final int[] p = new int[512];
        
        public PerlinNoise(int seed) {
            int[] perm = new int[256];
            for (int i = 0; i < 256; i++) perm[i] = i;
            
            Random r = new Random(seed);
            for (int i = 255; i > 0; i--) {
                int j = r.nextInt(i + 1);
                int t = perm[i];
                perm[i] = perm[j];
                perm[j] = t;
            }
            
            for (int i = 0; i < 256; i++) {
                int v = perm[i] & 255;
                p[i] = v;
                p[i + 256] = v;
            }
        }
        
        private static float fade(float t) {
            return t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f);
        }
        
        private static float lerp(float t, float a, float b) {
            return a + t * (b - a);
        }
        
        private static float grad(int hash, float x, float y, float z) {
            int h = hash & 15;
            float u = h < 8 ? x : y;
            float v = h < 4 ? y : (h == 12 || h == 14 ? x : z);
            return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
        }
        
        public float noise(float x, float y) {
            float z = 0.0f;
            int X = ((int) Math.floor(x)) & 255;
            int Y = ((int) Math.floor(y)) & 255;
            int Z = ((int) Math.floor(z)) & 255;
            
            x = (float) (x - Math.floor(x));
            y = (float) (y - Math.floor(y));
            z = (float) (z - Math.floor(z));
            
            float u = fade(x);
            float v = fade(y);
            float w = fade(z);
            
            int A = p[X] + Y;
            int AA = p[A] + Z;
            int AB = p[A + 1] + Z;
            int B = p[X + 1] + Y;
            int BA = p[B] + Z;
            int BB = p[B + 1] + Z;
            
            return lerp(w,
                lerp(v,
                    lerp(u, grad(p[AA], x, y, z), grad(p[BA], x - 1.0f, y, z)),
                    lerp(u, grad(p[AB], x, y - 1.0f, z), grad(p[BB], x - 1.0f, y - 1.0f, z))),
                lerp(v,
                    lerp(u, grad(p[AA + 1], x, y, z - 1.0f), grad(p[BA + 1], x - 1.0f, y, z - 1.0f)),
                    lerp(u, grad(p[AB + 1], x, y - 1.0f, z - 1.0f), grad(p[BB + 1], x - 1.0f, y - 1.0f, z - 1.0f))));
        }
        
        public float fbm(float x, float y, int octaves, float lacunarity, float gain) {
            float sum = 0.0f;
            float amp = 0.5f;
            float fx = x;
            float fy = y;
            
            for (int i = 0; i < octaves; i++) {
                sum += noise(fx, fy) * amp;
                fx *= lacunarity;
                fy *= lacunarity;
                amp *= gain;
            }
            
            return sum;
        }
    }
    
    private class InternalFTSnapRotation {
        
        private final PerlinNoise perlin = new PerlinNoise(1337);
        
        private static final float NOISE_YAW_MIN = 0.06f;
        private static final float NOISE_YAW_MAX = 0.38f;
        private static final float NOISE_PITCH_MIN = 0.04f;
        private static final float NOISE_PITCH_MAX = 0.22f;
        private static final float NOISE_FREQ_MIN = 0.55f;
        private static final float NOISE_FREQ_MAX = 1.65f;
        
        private float noisePhaseYaw = 0.0f;
        private float noisePhasePitch = 0.0f;
        
        private Vec3d mpCurrent = Vec3d.ZERO;
        private float mpOrbit = 0.0f;
        private long mpLastUpdate = 0L;
        private int mpLastTargetId = Integer.MIN_VALUE;
        
        private float critHeightOffset = 0.0f;
        private long lastAttackTime = 0L;
        
        private float overshootYaw = 0.0f;
        private float overshootPitch = 0.0f;
        private long overshootStartTime = 0L;
        private static final float OVERSHOOT_PROB = 0.25f;
        private static final float OVERSHOOT_MIN = 0.8f;
        private static final float OVERSHOOT_MAX = 2.5f;
        private static final long OVERSHOOT_DURATION = 80;
        
        private float smoothedYaw = 0.0f;
        private float smoothedPitch = 0.0f;
        private long smoothLastTime = 0L;
        private int smoothTargetId = -1;
        private long targetLockTime = 0L;
        private int lastLockedTargetId = -1;
        private float currentSpeedMultiplier = 1.0f;
        
        private boolean savedViewValid = false;
        private float savedYaw = 0.0f;
        private float savedPitch = 0.0f;
        private boolean returnActive = false;
        private long returnStartTime = 0L;
        private float returnYaw = 0.0f;
        private float returnPitch = 0.0f;
        public void notifyTargetChanged(LivingEntity newTarget) {
            if (newTarget == null) {
                lastLockedTargetId = -1;
                overshootYaw = 0.0f;
                overshootPitch = 0.0f;
                return;
            }
            
            int newId = newTarget.getId();
            
            if (lastLockedTargetId != newId) {
                lastLockedTargetId = newId;
                long now = System.currentTimeMillis();
                targetLockTime = now;
                
                currentSpeedMultiplier = rnd(0.65f, 0.95f);
                
                if (ThreadLocalRandom.current().nextFloat() < OVERSHOOT_PROB) {
                    overshootYaw = rnd(OVERSHOOT_MIN, OVERSHOOT_MAX) * (ThreadLocalRandom.current().nextBoolean() ? 1 : -1);
                    overshootPitch = rnd(OVERSHOOT_MIN * 0.6f, OVERSHOOT_MAX * 0.6f) * (ThreadLocalRandom.current().nextBoolean() ? 1 : -1);
                    overshootStartTime = now;
                } else {
                    overshootYaw = 0.0f;
                    overshootPitch = 0.0f;
                }
            }
        }
        
        public void updateSavedView() {
            if (mc.player == null) return;
            
            if (!savedViewValid) {
                savedViewValid = true;
                Rotation currentRotation = Holly.getInstance().getRotationHandler().getCurrentRotation();
                savedYaw = currentRotation.getYaw();
                savedPitch = currentRotation.getPitch();
            }
        }
        
        public void rotateTo(LivingEntity target, boolean attacking) {
            if (mc.player == null || target == null) return;
            
            updateSavedView();
            
            long now = System.currentTimeMillis();
            int tid = target.getId();
            
            if (smoothTargetId == -1) {
                Rotation currentRotation = Holly.getInstance().getRotationHandler().getCurrentRotation();
                smoothedYaw = currentRotation.getYaw();
                smoothedPitch = currentRotation.getPitch();
            }
            
            if (attacking && (now - lastAttackTime) > 400) {
                critHeightOffset = rnd(-0.15f, 0.15f);
                lastAttackTime = now;
            }
            
            float k = 0.035f;
            noisePhaseYaw += k * (0.65f + 0.35f * ((tid * 1103515245) & 255) / 255.0f);
            noisePhasePitch += k * (0.65f + 0.35f * ((tid * 1664525) & 255) / 255.0f);
            
            Vec3d targetPoint = getMultiPoint(target, attacking, now);
            
            Vec3d eyes = mc.player.getEyePos();
            Vec3d direction = targetPoint.subtract(eyes);
            
            double horizontalDistance = Math.sqrt(direction.x * direction.x + direction.z * direction.z);
            
            float targetYaw = (float) Math.toDegrees(Math.atan2(direction.z, direction.x)) - 90.0F;
            float targetPitch = (float) (-Math.toDegrees(Math.atan2(direction.y, horizontalDistance)));
            
            targetYaw = normalizeAngle(targetYaw);
            targetPitch = clamp(targetPitch, -90.0f, 90.0f);
            
            if (smoothTargetId != tid) {
                smoothTargetId = tid;
                smoothLastTime = now;
            }
            
            long dtMs = now - smoothLastTime;
            if (dtMs < 1) dtMs = 1;
            if (dtMs > 120) dtMs = 120;
            smoothLastTime = now;
            
            long timeSinceLock = now - targetLockTime;
            float lockProgress = Math.min(1.0f, timeSinceLock / 1000.0f);
            
            float speedMultiplier = lockProgress * lockProgress * (3.0f - 2.0f * lockProgress);
            speedMultiplier = 0.35f + speedMultiplier * 0.65f;
            speedMultiplier *= currentSpeedMultiplier;
            
            float baseYawSpeed = attacking ? 55.0f : 60.0f;
            float basePitchSpeed = attacking ? 44.0f : 48.0f;
            
            float yawSpeed = baseYawSpeed * speedMultiplier;
            float pitchSpeed = basePitchSpeed * speedMultiplier;
            
            float yawMaxDelta = yawSpeed * ((float) dtMs / 50.0f);
            float pitchMaxDelta = pitchSpeed * ((float) dtMs / 50.0f);
            
            float yawError = normalizeAngle(targetYaw - smoothedYaw);
            float pitchError = targetPitch - smoothedPitch;
            
            smoothedYaw += clamp(yawError, -yawMaxDelta, yawMaxDelta);
            smoothedPitch += clamp(pitchError, -pitchMaxDelta, pitchMaxDelta);
            
            smoothedYaw = normalizeAngle(smoothedYaw);
            smoothedPitch = clamp(smoothedPitch, -90.0f, 90.0f);
            
            float overshootFactor = 0.0f;
            if (overshootYaw != 0.0f || overshootPitch != 0.0f) {
                long timeSinceOvershoot = now - overshootStartTime;
                if (timeSinceOvershoot < OVERSHOOT_DURATION) {
                    overshootFactor = 1.0f - ((float) timeSinceOvershoot / OVERSHOOT_DURATION);
                    overshootFactor = overshootFactor * overshootFactor;
                } else {
                    overshootYaw = 0.0f;
                    overshootPitch = 0.0f;
                }
            }
            
            float jitterYaw = getJitter(now, tid, true);
            float jitterPitch = getJitter(now, tid, false);
            
            float finalYaw = smoothedYaw + jitterYaw + (overshootYaw * overshootFactor);
            float finalPitch = smoothedPitch + jitterPitch + (overshootPitch * overshootFactor);
            
            finalYaw = normalizeAngle(finalYaw);
            finalPitch = clamp(finalPitch, -90.0f, 90.0f);
            
            Rotation rotation = new Rotation(finalYaw, finalPitch);
            Holly.getInstance().getRotationHandler().rotate(
                rotation,
                MoveCorrection.SILENT,
                180.0f,
                180.0f,
                180.0f,
                RotationPriority.OVERRIDE
            );
        }
        
        private Vec3d getMultiPoint(LivingEntity target, boolean attacking, long now) {
            int tid = target.getId();
            
            if (tid != mpLastTargetId) {
                mpLastTargetId = tid;
                mpCurrent = Vec3d.ZERO;
                mpOrbit = rnd(0.0f, (float) (Math.PI * 2.0));
                mpLastUpdate = now;
            }
            
            long dtMs = now - mpLastUpdate;
            if (dtMs < 1) dtMs = 1;
            if (dtMs > 60) dtMs = 60;
            mpLastUpdate = now;
            
            float orbitSpeed = 0.36f;
            float dtScale = (float) dtMs / 50.0f;
            mpOrbit += orbitSpeed * dtScale + rnd(-0.018f, 0.018f) * dtScale;
            
            Vec3d desired = calculateOrbitPoint(mpOrbit, attacking);
            
            float tau = 120.0f;
            float alpha = (float) dtMs / tau;
            alpha = clamp(alpha, 0.0f, 1.0f);
            alpha = alpha * alpha * (3.0f - 2.0f * alpha);
            
            if (mpCurrent == Vec3d.ZERO) {
                mpCurrent = desired;
            } else {
                mpCurrent = new Vec3d(
                    lerp(mpCurrent.x, desired.x, alpha),
                    lerp(mpCurrent.y, desired.y, alpha),
                    lerp(mpCurrent.z, desired.z, alpha)
                );
            }
            
            Box box = target.getBoundingBox();
            double fx = 0.5 + mpCurrent.x * 0.5;
            double fy = mpCurrent.y;
            double fz = 0.5 + mpCurrent.z * 0.5;
            
            fx = clamp(fx, 0.0, 1.0);
            fy = clamp(fy, 0.36, 0.82);
            fz = clamp(fz, 0.0, 1.0);
            
            double x = box.minX + (box.maxX - box.minX) * fx;
            double y = box.minY + (box.maxY - box.minY) * fy;
            double z = box.minZ + (box.maxZ - box.minZ) * fz;
            
            return new Vec3d(
                clamp(x, box.minX + 1.0E-4, box.maxX - 1.0E-4),
                clamp(y, box.minY + 1.0E-4, box.maxY - 1.0E-4),
                clamp(z, box.minZ + 1.0E-4, box.maxZ - 1.0E-4)
            );
        }
        
        private Vec3d calculateOrbitPoint(float orbit, boolean attacking) {
            float o = orbit;
            
            float y = 0.56f
                + 0.10f * (float) Math.sin(o * 0.74f + 0.9f)
                + 0.06f * (float) Math.sin(o * 1.28f + 2.2f)
                - 0.05f * (float) (0.5 + 0.5 * Math.sin(o * 0.35f + 1.7f))
                + critHeightOffset;
            
            float x = (0.22f * (float) Math.sin(o))
                + (0.06f * (float) Math.sin(o * 1.85f + 0.25f));
            
            float z = (0.08f * (float) Math.cos(o * 0.92f + 0.4f))
                + (0.03f * (float) Math.sin(o * 1.35f + 1.1f));
            
            float jitter = 0.020f;
            x += rnd(-jitter, jitter);
            z += rnd(-jitter, jitter);
            y += rnd(-jitter * 0.55f, jitter * 0.55f);
            
            x = clamp(x, -0.46f, 0.46f);
            z = clamp(z, -0.36f, 0.36f);
            y = clamp(y, 0.36f, 0.82f);
            
            return new Vec3d(x, y, z);
        }
        
        private float getJitter(long now, int tid, boolean isYaw) {
            float amp = isYaw
                ? lerp(NOISE_YAW_MIN, NOISE_YAW_MAX, 0.5f)
                : lerp(NOISE_PITCH_MIN, NOISE_PITCH_MAX, 0.5f);
            
            float freq = lerp(NOISE_FREQ_MIN, NOISE_FREQ_MAX, 0.5f);
            
            float phase = isYaw ? noisePhaseYaw : noisePhasePitch;
            float tt = (float) ((now % 100000L) / 1000.0);
            
            float noise = perlin.fbm((tt * freq + phase), (float) (tid * 0.013 + 0.11), 4, 2.0f, 0.55f);
            float sway = perlin.noise((tt * 0.22f + phase * 0.07f), (float) (tid * 0.009 + 9.3));
            
            return (noise * 0.72f + sway * 0.28f) * amp;
        }
        
        public void reset() {
            noisePhaseYaw = rnd(0.0f, 999.0f);
            noisePhasePitch = rnd(0.0f, 999.0f);
            mpCurrent = Vec3d.ZERO;
            mpOrbit = 0.0f;
            mpLastUpdate = 0L;
            mpLastTargetId = Integer.MIN_VALUE;
            smoothedYaw = 0.0f;
            smoothedPitch = 0.0f;
            smoothLastTime = 0L;
            smoothTargetId = -1;
            targetLockTime = 0L;
            lastLockedTargetId = -1;
            currentSpeedMultiplier = 1.0f;
            savedViewValid = false;
            returnActive = false;
            overshootYaw = 0.0f;
            overshootPitch = 0.0f;
        }
        
        private float normalizeAngle(float angle) {
            angle = angle % 360.0F;
            if (angle >= 180.0F) angle -= 360.0F;
            if (angle < -180.0F) angle += 360.0F;
            return angle;
        }
        
        private static float clamp(float value, float min, float max) {
            if (value < min) return min;
            if (value > max) return max;
            return value;
        }
        
        private static double clamp(double value, double min, double max) {
            if (value < min) return min;
            if (value > max) return max;
            return value;
        }
        
        private static float lerp(float a, float b, float t) {
            return a + (b - a) * t;
        }
        
        private static double lerp(double a, double b, double t) {
            return a + (b - a) * t;
        }
    }
    
    private static RotatingHitbox instance;
    
    private final TargetFinder targetFinder = new TargetFinder();
    private final InternalFTSnapRotation ftSnapRotation = new InternalFTSnapRotation();
    private final SliderSetting attackRange = new SliderSetting(this, "Дистанция поиска")
        .min(1.0F).max(6.0F).step(0.1F).currentValue(3.5F);
    
    private final SliderSetting expandSize = new SliderSetting(this, "Размер увеличения")
        .min(0.1F).max(2.0F).step(0.1F).currentValue(0.5F);
    
    private final SelectSetting targetTypes = new SelectSetting(this, "Типы целей");
    private final SelectSetting.Value players = new SelectSetting.Value(targetTypes, "Players").select();
    private final SelectSetting.Value mobs = new SelectSetting.Value(targetTypes, "Mobs").select();
    private final SelectSetting.Value animals = new SelectSetting.Value(targetTypes, "Animals");
    
    private final BooleanSetting ignoreWalls = new BooleanSetting(this, "Игнорировать стены");
    
    private final BooleanSetting antiReach = new BooleanSetting(this, "Анти-Reach");
    
    private final SliderSetting antiReachDistance = new SliderSetting(this, "Дистанция Анти-Reach")
        .min(1.0F).max(3.0F).step(0.01F).currentValue(2.85F);
    
    private final BooleanSetting fakeSwing = new BooleanSetting(this, "Фейк свинг");
    
    private final BooleanSetting legitSprint = new BooleanSetting(this, "Легит спринт")
        .enable();
    
    private final BooleanSetting autoTargetESP = new BooleanSetting(this, "Авто TargetESP")
        .enable();
    
    private final SliderSetting lineWidth = new SliderSetting(this, "Толщина линий")
        .min(1.0F).max(5.0F).step(0.5F).currentValue(2.5F);
    
    private final ColorSetting hitboxColor = new ColorSetting(this, "Цвет хитбокса")
        .color(new ColorRGBA(100, 150, 255, 100));
    
    private final ColorSetting activeColor = new ColorSetting(this, "Цвет при активации")
        .color(new ColorRGBA(255, 50, 50, 120));
    
    private LivingEntity currentTarget = null;
    private boolean isAimingAtHitbox = false;
    
    private boolean sprintResetActive = false;
    private long sprintResetStartTime = 0;
    private static final long SPRINT_RESET_DURATION = 250;
    
    private final Map<Integer, Box> originalHitboxes = new HashMap<>();
    
    public RotatingHitbox() {
        instance = this;
    }
    
    public static RotatingHitbox getInstance() {
        return instance;
    }
    
    private final EventListener<ClientPlayerTickEvent> onTick = event -> {
        if (mc.player == null || mc.world == null) {
            resetState();
            return;
        }
        
        List<String> selectedTypes = targetTypes.getSelectedValues().stream()
            .map(SelectSetting.Value::getName)
            .toList();
        
        targetFinder.searchTargets(
            attackRange.getCurrentValue(),
            90.0f,
            ignoreWalls.isEnabled(),
            selectedTypes
        );
        
        targetFinder.validateTarget(target -> {
            if (target == null || !target.isAlive() || target.getHealth() <= 0) {
                return false;
            }
            
            float distance = mc.player.distanceTo(target);
            return distance <= attackRange.getCurrentValue();
        });
        
        LivingEntity previousTarget = currentTarget;
        currentTarget = targetFinder.getCurrentTarget();
        
        if (currentTarget != previousTarget) {
            ftSnapRotation.notifyTargetChanged(currentTarget);
        }
        
        if (currentTarget != null) {
            isAimingAtHitbox = isLookingAtExpandedHitbox();
            
            if (isAimingAtHitbox && !isAuraEnabled()) {
                ftSnapRotation.updateSavedView();
                ftSnapRotation.rotateTo(currentTarget, false);
                
                if (legitSprint.isEnabled()) {
                    handleLegitSprintReset();
                }
            }
            
            if (autoTargetESP.isEnabled()) {
                Holly.getInstance().getTargetManager().setCurrentTarget(currentTarget);
            }
        } else {
            sprintResetActive = false;
            
            if (autoTargetESP.isEnabled()) {
                Holly.getInstance().getTargetManager().setCurrentTarget(null);
            }
        }
    };
    
    private final EventListener<Render3DEvent> onRender3D = event -> {
        if (mc.player == null || mc.world == null) {
            return;
        }
        
        List<String> selectedTypes = targetTypes.getSelectedValues().stream()
            .map(SelectSetting.Value::getName)
            .toList();
        
        for (Entity entity : mc.world.getEntities()) {
            if (entity instanceof LivingEntity livingEntity && livingEntity != mc.player) {
                boolean isValidType = false;
                for (String type : selectedTypes) {
                    if (type.equals("Players") && livingEntity instanceof net.minecraft.entity.player.PlayerEntity) {
                        isValidType = true;
                        break;
                    } else if (type.equals("Mobs") && livingEntity instanceof net.minecraft.entity.mob.MobEntity) {
                        isValidType = true;
                        break;
                    } else if (type.equals("Animals") && livingEntity instanceof net.minecraft.entity.passive.AnimalEntity) {
                        isValidType = true;
                        break;
                    }
                }
                
                if (isValidType && livingEntity.isAlive()) {
                    int id = livingEntity.getId();
                    
                    if (!originalHitboxes.containsKey(id)) {
                        originalHitboxes.put(id, getOriginalHitbox(livingEntity));
                    }
                    
                    float radius = getEntityRadius(livingEntity);
                    float expandedRadius = radius + expandSize.getCurrentValue();
                    setEntityHitbox(livingEntity, expandedRadius);
                    
                    Box expandedBox = calculateExpandedHitbox(livingEntity);
                    boolean isCurrentTarget = (livingEntity == currentTarget && isAimingAtHitbox);
                    renderHitbox(event.getMatrices(), expandedBox, isCurrentTarget);
                }
            }
        }
    };
    
    private final EventListener<AttackEvent> onAttack = event -> {
        Entity target = event.getEntity();
        
        if (legitSprint.isEnabled() && target instanceof LivingEntity) {
            sprintResetActive = true;
            sprintResetStartTime = System.currentTimeMillis();
        }
        
        if (!antiReach.isEnabled() || mc.player == null) {
            return;
        }
        
        if (!(target instanceof LivingEntity livingEntity)) {
            return;
        }
        
        if (livingEntity == mc.player) {
            return;
        }
        
        Box originalBox = getOriginalHitbox(livingEntity);
        Vec3d eyes = mc.player.getEyePos();
        Vec3d closestPoint = getClosestPoint(eyes, originalBox);
        double distance = eyes.distanceTo(closestPoint);
        
        double maxDistance = antiReachDistance.getCurrentValue();
        
        if (distance > maxDistance) {
            event.cancel();
            
            if (fakeSwing.isEnabled() && mc.player != null) {
                mc.player.swingHand(net.minecraft.util.Hand.MAIN_HAND);
                mc.player.resetLastAttackedTicks();
            }
        }
    };
    
    private Box getOriginalHitbox(Entity entity) {
        return entity.getType().getDimensions().getBoxAt(entity.getPos());
    }
    
    private float getEntityRadius(Entity entity) {
        Box box = getOriginalHitbox(entity);
        return (float)(box.getLengthX() / 2.0);
    }
    
    private void setEntityHitbox(LivingEntity entity, float radius) {
        entity.setBoundingBox(
            new Box(
                entity.getX() - radius,
                entity.getBoundingBox().minY,
                entity.getZ() - radius,
                entity.getX() + radius,
                entity.getBoundingBox().maxY,
                entity.getZ() + radius
            )
        );
    }
    
    private Box calculateExpandedHitbox(LivingEntity target) {
        float radius = getEntityRadius(target);
        float expandedRadius = radius + expandSize.getCurrentValue();
        
        return new Box(
            target.getX() - expandedRadius,
            target.getBoundingBox().minY,
            target.getZ() - expandedRadius,
            target.getX() + expandedRadius,
            target.getBoundingBox().maxY,
            target.getZ() + expandedRadius
        );
    }
    
    private boolean isLookingAtExpandedHitbox() {
        if (mc.player == null || currentTarget == null) {
            return false;
        }
        
        float yaw = mc.player.getYaw();
        float pitch = mc.player.getPitch();
        
        float yawRad = (float) Math.toRadians(yaw);
        float pitchRad = (float) Math.toRadians(pitch);
        
        float x = (float)(-Math.sin(yawRad) * Math.cos(pitchRad));
        float y = (float)(-Math.sin(pitchRad));
        float z = (float)(Math.cos(yawRad) * Math.cos(pitchRad));
        Vec3d direction = new Vec3d(x, y, z);
        
        Vec3d eyes = mc.player.getEyePos();
        
        Box expandedBox = calculateExpandedHitbox(currentTarget);
        
        if (expandedBox.contains(eyes)) {
            return true;
        }
        
        Vec3d end = eyes.add(direction.multiply(attackRange.getCurrentValue() + 2.0));
        return expandedBox.raycast(eyes, end).isPresent();
    }
    
    private void resetState() {
        isAimingAtHitbox = false;
    }
    
    private void handleLegitSprintReset() {
        if (mc.player == null) return;
        
        long currentTime = System.currentTimeMillis();
        
        if (sprintResetActive) {
            mc.options.sprintKey.setPressed(false);
            mc.player.setSprinting(false);
            
            if (currentTime - sprintResetStartTime >= SPRINT_RESET_DURATION) {
                sprintResetActive = false;
            }
        }
    }
    
    private boolean isAuraEnabled() {
        return Holly.getInstance().getModuleManager().getModule(Aura.class).isEnabled();
    }
    
    private void restoreAllHitboxes() {
        if (mc.world == null) return;
        
        for (Entity entity : mc.world.getEntities()) {
            if (entity instanceof LivingEntity livingEntity && livingEntity != mc.player) {
                int id = livingEntity.getId();
                if (originalHitboxes.containsKey(id)) {
                    float radius = getEntityRadius(livingEntity);
                    setEntityHitbox(livingEntity, radius);
                }
            }
        }
        
        originalHitboxes.clear();
    }
    
    private Vec3d getClosestPoint(Vec3d point, Box box) {
        double x = Math.max(box.minX, Math.min(point.x, box.maxX));
        double y = Math.max(box.minY, Math.min(point.y, box.maxY));
        double z = Math.max(box.minZ, Math.min(point.z, box.maxZ));
        return new Vec3d(x, y, z);
    }
    
    private void renderHitbox(MatrixStack matrices, Box box, boolean active) {
        if (mc.player == null) return;
        
        matrices.push();
        
        RenderSystem.enableBlend();
        RenderSystem.defaultBlendFunc();
        RenderSystem.disableDepthTest();
        RenderSystem.disableCull();
        RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR);
        RenderSystem.lineWidth(lineWidth.getCurrentValue());
        
        Vec3d cameraPos = mc.gameRenderer.getCamera().getPos();
        matrices.translate(-cameraPos.x, -cameraPos.y, -cameraPos.z);
        
        ColorRGBA color = active ? activeColor.getColor() : hitboxColor.getColor();
        
        drawBoxFilled(matrices, box, color);
        
        ColorRGBA outlineColor = new ColorRGBA(
            Math.min(255, color.getRed() + 50),
            Math.min(255, color.getGreen() + 50),
            Math.min(255, color.getBlue() + 50),
            Math.min(255, color.getAlpha() + 80)
        );
        drawBoxOutline(matrices, box, outlineColor);
        
        RenderSystem.lineWidth(1.0f);
        RenderSystem.enableDepthTest();
        RenderSystem.enableCull();
        RenderSystem.disableBlend();
        
        matrices.pop();
    }
    
    private void drawBoxFilled(MatrixStack matrices, Box box, ColorRGBA color) {
        Matrix4f matrix = matrices.peek().getPositionMatrix();
        
        Tessellator tessellator = Tessellator.getInstance();
        BufferBuilder buffer = tessellator.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR);
        
        float r = color.getRed() / 255.0f;
        float g = color.getGreen() / 255.0f;
        float b = color.getBlue() / 255.0f;
        float a = color.getAlpha() / 255.0f * 0.5f;
        
        float minX = (float) box.minX;
        float minY = (float) box.minY;
        float minZ = (float) box.minZ;
        float maxX = (float) box.maxX;
        float maxY = (float) box.maxY;
        float maxZ = (float) box.maxZ;
        
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
        
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
        
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
        
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
        
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
        
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
        
        BufferRenderer.drawWithGlobalProgram(buffer.end());
    }
    
    private void drawBoxOutline(MatrixStack matrices, Box box, ColorRGBA color) {
        Matrix4f matrix = matrices.peek().getPositionMatrix();
        
        Tessellator tessellator = Tessellator.getInstance();
        BufferBuilder buffer = tessellator.begin(VertexFormat.DrawMode.DEBUG_LINES, VertexFormats.POSITION_COLOR);
        
        float r = color.getRed() / 255.0f;
        float g = color.getGreen() / 255.0f;
        float b = color.getBlue() / 255.0f;
        float a = color.getAlpha() / 255.0f;
        
        float minX = (float) box.minX;
        float minY = (float) box.minY;
        float minZ = (float) box.minZ;
        float maxX = (float) box.maxX;
        float maxY = (float) box.maxY;
        float maxZ = (float) box.maxZ;
        
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
        
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
        
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
        
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
        
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
        
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
        
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
        
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
        
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
        
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
        
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
        
        BufferRenderer.drawWithGlobalProgram(buffer.end());
    }
    
    @Override
    public void onEnable() {
        targetFinder.releaseTarget();
        currentTarget = null;
        isAimingAtHitbox = false;
        originalHitboxes.clear();
        ftSnapRotation.reset();
        sprintResetActive = false;
        sprintResetStartTime = 0;
    }
    
    @Override
    public void onDisable() {
        targetFinder.releaseTarget();
        currentTarget = null;
        isAimingAtHitbox = false;
        restoreAllHitboxes();
        ftSnapRotation.reset();
        sprintResetActive = false;
        
        if (autoTargetESP.isEnabled()) {
            Holly.getInstance().getTargetManager().setCurrentTarget(null);
        }
    }
    
    private static float rnd(float a, float b) {
        if (b <= a) return a;
        return a + ThreadLocalRandom.current().nextFloat() * (b - a);
    }
}
 
Всем привет, решил сделать снап хитбоксы под базу рокстара
В кратце эт не снапы а хиты с норм ротацией под фт, это не перенсос с система! ГПТ код имееться
Пожалуйста, авторизуйтесь для просмотра ссылки.

Java:
Expand Collapse Copy
package moscow.holly.systems.modules.modules.combat;

import com.mojang.blaze3d.systems.RenderSystem;
import moscow.holly.systems.event.EventListener;
import moscow.holly.systems.event.impl.game.AttackEvent;
import moscow.holly.systems.event.impl.player.ClientPlayerTickEvent;
import moscow.holly.systems.event.impl.render.Render3DEvent;
import moscow.holly.systems.modules.api.ModuleCategory;
import moscow.holly.systems.modules.api.ModuleInfo;
import moscow.holly.systems.modules.impl.BaseModule;
import moscow.holly.systems.setting.settings.BooleanSetting;
import moscow.holly.systems.setting.settings.ColorSetting;
import moscow.holly.systems.setting.settings.SelectSetting;
import moscow.holly.systems.setting.settings.SliderSetting;
import moscow.holly.Holly;
import moscow.holly.systems.modules.modules.combat.Aura;
import moscow.holly.utility.colors.ColorRGBA;
import moscow.holly.utility.combat.aura.TargetFinder;
import moscow.holly.utility.rotations.MoveCorrection;
import moscow.holly.utility.rotations.Rotation;
import moscow.holly.utility.rotations.RotationPriority;
import net.minecraft.client.gl.ShaderProgramKeys;
import net.minecraft.client.render.*;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
import org.joml.Matrix4f;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

@ModuleInfo(name = "Rotating Hitbox", category = ModuleCategory.COMBAT, desc = "Увеличенный хитбокс с ротацией как в Aura-Funtime")
public class RotatingHitbox extends BaseModule {
   
    private static class PerlinNoise {
        private final int[] p = new int[512];
       
        public PerlinNoise(int seed) {
            int[] perm = new int[256];
            for (int i = 0; i < 256; i++) perm[i] = i;
           
            Random r = new Random(seed);
            for (int i = 255; i > 0; i--) {
                int j = r.nextInt(i + 1);
                int t = perm[i];
                perm[i] = perm[j];
                perm[j] = t;
            }
           
            for (int i = 0; i < 256; i++) {
                int v = perm[i] & 255;
                p[i] = v;
                p[i + 256] = v;
            }
        }
       
        private static float fade(float t) {
            return t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f);
        }
       
        private static float lerp(float t, float a, float b) {
            return a + t * (b - a);
        }
       
        private static float grad(int hash, float x, float y, float z) {
            int h = hash & 15;
            float u = h < 8 ? x : y;
            float v = h < 4 ? y : (h == 12 || h == 14 ? x : z);
            return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
        }
       
        public float noise(float x, float y) {
            float z = 0.0f;
            int X = ((int) Math.floor(x)) & 255;
            int Y = ((int) Math.floor(y)) & 255;
            int Z = ((int) Math.floor(z)) & 255;
           
            x = (float) (x - Math.floor(x));
            y = (float) (y - Math.floor(y));
            z = (float) (z - Math.floor(z));
           
            float u = fade(x);
            float v = fade(y);
            float w = fade(z);
           
            int A = p[X] + Y;
            int AA = p[A] + Z;
            int AB = p[A + 1] + Z;
            int B = p[X + 1] + Y;
            int BA = p[B] + Z;
            int BB = p[B + 1] + Z;
           
            return lerp(w,
                lerp(v,
                    lerp(u, grad(p[AA], x, y, z), grad(p[BA], x - 1.0f, y, z)),
                    lerp(u, grad(p[AB], x, y - 1.0f, z), grad(p[BB], x - 1.0f, y - 1.0f, z))),
                lerp(v,
                    lerp(u, grad(p[AA + 1], x, y, z - 1.0f), grad(p[BA + 1], x - 1.0f, y, z - 1.0f)),
                    lerp(u, grad(p[AB + 1], x, y - 1.0f, z - 1.0f), grad(p[BB + 1], x - 1.0f, y - 1.0f, z - 1.0f))));
        }
       
        public float fbm(float x, float y, int octaves, float lacunarity, float gain) {
            float sum = 0.0f;
            float amp = 0.5f;
            float fx = x;
            float fy = y;
           
            for (int i = 0; i < octaves; i++) {
                sum += noise(fx, fy) * amp;
                fx *= lacunarity;
                fy *= lacunarity;
                amp *= gain;
            }
           
            return sum;
        }
    }
   
    private class InternalFTSnapRotation {
       
        private final PerlinNoise perlin = new PerlinNoise(1337);
       
        private static final float NOISE_YAW_MIN = 0.06f;
        private static final float NOISE_YAW_MAX = 0.38f;
        private static final float NOISE_PITCH_MIN = 0.04f;
        private static final float NOISE_PITCH_MAX = 0.22f;
        private static final float NOISE_FREQ_MIN = 0.55f;
        private static final float NOISE_FREQ_MAX = 1.65f;
       
        private float noisePhaseYaw = 0.0f;
        private float noisePhasePitch = 0.0f;
       
        private Vec3d mpCurrent = Vec3d.ZERO;
        private float mpOrbit = 0.0f;
        private long mpLastUpdate = 0L;
        private int mpLastTargetId = Integer.MIN_VALUE;
       
        private float critHeightOffset = 0.0f;
        private long lastAttackTime = 0L;
       
        private float overshootYaw = 0.0f;
        private float overshootPitch = 0.0f;
        private long overshootStartTime = 0L;
        private static final float OVERSHOOT_PROB = 0.25f;
        private static final float OVERSHOOT_MIN = 0.8f;
        private static final float OVERSHOOT_MAX = 2.5f;
        private static final long OVERSHOOT_DURATION = 80;
       
        private float smoothedYaw = 0.0f;
        private float smoothedPitch = 0.0f;
        private long smoothLastTime = 0L;
        private int smoothTargetId = -1;
        private long targetLockTime = 0L;
        private int lastLockedTargetId = -1;
        private float currentSpeedMultiplier = 1.0f;
       
        private boolean savedViewValid = false;
        private float savedYaw = 0.0f;
        private float savedPitch = 0.0f;
        private boolean returnActive = false;
        private long returnStartTime = 0L;
        private float returnYaw = 0.0f;
        private float returnPitch = 0.0f;
        public void notifyTargetChanged(LivingEntity newTarget) {
            if (newTarget == null) {
                lastLockedTargetId = -1;
                overshootYaw = 0.0f;
                overshootPitch = 0.0f;
                return;
            }
           
            int newId = newTarget.getId();
           
            if (lastLockedTargetId != newId) {
                lastLockedTargetId = newId;
                long now = System.currentTimeMillis();
                targetLockTime = now;
               
                currentSpeedMultiplier = rnd(0.65f, 0.95f);
               
                if (ThreadLocalRandom.current().nextFloat() < OVERSHOOT_PROB) {
                    overshootYaw = rnd(OVERSHOOT_MIN, OVERSHOOT_MAX) * (ThreadLocalRandom.current().nextBoolean() ? 1 : -1);
                    overshootPitch = rnd(OVERSHOOT_MIN * 0.6f, OVERSHOOT_MAX * 0.6f) * (ThreadLocalRandom.current().nextBoolean() ? 1 : -1);
                    overshootStartTime = now;
                } else {
                    overshootYaw = 0.0f;
                    overshootPitch = 0.0f;
                }
            }
        }
       
        public void updateSavedView() {
            if (mc.player == null) return;
           
            if (!savedViewValid) {
                savedViewValid = true;
                Rotation currentRotation = Holly.getInstance().getRotationHandler().getCurrentRotation();
                savedYaw = currentRotation.getYaw();
                savedPitch = currentRotation.getPitch();
            }
        }
       
        public void rotateTo(LivingEntity target, boolean attacking) {
            if (mc.player == null || target == null) return;
           
            updateSavedView();
           
            long now = System.currentTimeMillis();
            int tid = target.getId();
           
            if (smoothTargetId == -1) {
                Rotation currentRotation = Holly.getInstance().getRotationHandler().getCurrentRotation();
                smoothedYaw = currentRotation.getYaw();
                smoothedPitch = currentRotation.getPitch();
            }
           
            if (attacking && (now - lastAttackTime) > 400) {
                critHeightOffset = rnd(-0.15f, 0.15f);
                lastAttackTime = now;
            }
           
            float k = 0.035f;
            noisePhaseYaw += k * (0.65f + 0.35f * ((tid * 1103515245) & 255) / 255.0f);
            noisePhasePitch += k * (0.65f + 0.35f * ((tid * 1664525) & 255) / 255.0f);
           
            Vec3d targetPoint = getMultiPoint(target, attacking, now);
           
            Vec3d eyes = mc.player.getEyePos();
            Vec3d direction = targetPoint.subtract(eyes);
           
            double horizontalDistance = Math.sqrt(direction.x * direction.x + direction.z * direction.z);
           
            float targetYaw = (float) Math.toDegrees(Math.atan2(direction.z, direction.x)) - 90.0F;
            float targetPitch = (float) (-Math.toDegrees(Math.atan2(direction.y, horizontalDistance)));
           
            targetYaw = normalizeAngle(targetYaw);
            targetPitch = clamp(targetPitch, -90.0f, 90.0f);
           
            if (smoothTargetId != tid) {
                smoothTargetId = tid;
                smoothLastTime = now;
            }
           
            long dtMs = now - smoothLastTime;
            if (dtMs < 1) dtMs = 1;
            if (dtMs > 120) dtMs = 120;
            smoothLastTime = now;
           
            long timeSinceLock = now - targetLockTime;
            float lockProgress = Math.min(1.0f, timeSinceLock / 1000.0f);
           
            float speedMultiplier = lockProgress * lockProgress * (3.0f - 2.0f * lockProgress);
            speedMultiplier = 0.35f + speedMultiplier * 0.65f;
            speedMultiplier *= currentSpeedMultiplier;
           
            float baseYawSpeed = attacking ? 55.0f : 60.0f;
            float basePitchSpeed = attacking ? 44.0f : 48.0f;
           
            float yawSpeed = baseYawSpeed * speedMultiplier;
            float pitchSpeed = basePitchSpeed * speedMultiplier;
           
            float yawMaxDelta = yawSpeed * ((float) dtMs / 50.0f);
            float pitchMaxDelta = pitchSpeed * ((float) dtMs / 50.0f);
           
            float yawError = normalizeAngle(targetYaw - smoothedYaw);
            float pitchError = targetPitch - smoothedPitch;
           
            smoothedYaw += clamp(yawError, -yawMaxDelta, yawMaxDelta);
            smoothedPitch += clamp(pitchError, -pitchMaxDelta, pitchMaxDelta);
           
            smoothedYaw = normalizeAngle(smoothedYaw);
            smoothedPitch = clamp(smoothedPitch, -90.0f, 90.0f);
           
            float overshootFactor = 0.0f;
            if (overshootYaw != 0.0f || overshootPitch != 0.0f) {
                long timeSinceOvershoot = now - overshootStartTime;
                if (timeSinceOvershoot < OVERSHOOT_DURATION) {
                    overshootFactor = 1.0f - ((float) timeSinceOvershoot / OVERSHOOT_DURATION);
                    overshootFactor = overshootFactor * overshootFactor;
                } else {
                    overshootYaw = 0.0f;
                    overshootPitch = 0.0f;
                }
            }
           
            float jitterYaw = getJitter(now, tid, true);
            float jitterPitch = getJitter(now, tid, false);
           
            float finalYaw = smoothedYaw + jitterYaw + (overshootYaw * overshootFactor);
            float finalPitch = smoothedPitch + jitterPitch + (overshootPitch * overshootFactor);
           
            finalYaw = normalizeAngle(finalYaw);
            finalPitch = clamp(finalPitch, -90.0f, 90.0f);
           
            Rotation rotation = new Rotation(finalYaw, finalPitch);
            Holly.getInstance().getRotationHandler().rotate(
                rotation,
                MoveCorrection.SILENT,
                180.0f,
                180.0f,
                180.0f,
                RotationPriority.OVERRIDE
            );
        }
       
        private Vec3d getMultiPoint(LivingEntity target, boolean attacking, long now) {
            int tid = target.getId();
           
            if (tid != mpLastTargetId) {
                mpLastTargetId = tid;
                mpCurrent = Vec3d.ZERO;
                mpOrbit = rnd(0.0f, (float) (Math.PI * 2.0));
                mpLastUpdate = now;
            }
           
            long dtMs = now - mpLastUpdate;
            if (dtMs < 1) dtMs = 1;
            if (dtMs > 60) dtMs = 60;
            mpLastUpdate = now;
           
            float orbitSpeed = 0.36f;
            float dtScale = (float) dtMs / 50.0f;
            mpOrbit += orbitSpeed * dtScale + rnd(-0.018f, 0.018f) * dtScale;
           
            Vec3d desired = calculateOrbitPoint(mpOrbit, attacking);
           
            float tau = 120.0f;
            float alpha = (float) dtMs / tau;
            alpha = clamp(alpha, 0.0f, 1.0f);
            alpha = alpha * alpha * (3.0f - 2.0f * alpha);
           
            if (mpCurrent == Vec3d.ZERO) {
                mpCurrent = desired;
            } else {
                mpCurrent = new Vec3d(
                    lerp(mpCurrent.x, desired.x, alpha),
                    lerp(mpCurrent.y, desired.y, alpha),
                    lerp(mpCurrent.z, desired.z, alpha)
                );
            }
           
            Box box = target.getBoundingBox();
            double fx = 0.5 + mpCurrent.x * 0.5;
            double fy = mpCurrent.y;
            double fz = 0.5 + mpCurrent.z * 0.5;
           
            fx = clamp(fx, 0.0, 1.0);
            fy = clamp(fy, 0.36, 0.82);
            fz = clamp(fz, 0.0, 1.0);
           
            double x = box.minX + (box.maxX - box.minX) * fx;
            double y = box.minY + (box.maxY - box.minY) * fy;
            double z = box.minZ + (box.maxZ - box.minZ) * fz;
           
            return new Vec3d(
                clamp(x, box.minX + 1.0E-4, box.maxX - 1.0E-4),
                clamp(y, box.minY + 1.0E-4, box.maxY - 1.0E-4),
                clamp(z, box.minZ + 1.0E-4, box.maxZ - 1.0E-4)
            );
        }
       
        private Vec3d calculateOrbitPoint(float orbit, boolean attacking) {
            float o = orbit;
           
            float y = 0.56f
                + 0.10f * (float) Math.sin(o * 0.74f + 0.9f)
                + 0.06f * (float) Math.sin(o * 1.28f + 2.2f)
                - 0.05f * (float) (0.5 + 0.5 * Math.sin(o * 0.35f + 1.7f))
                + critHeightOffset;
           
            float x = (0.22f * (float) Math.sin(o))
                + (0.06f * (float) Math.sin(o * 1.85f + 0.25f));
           
            float z = (0.08f * (float) Math.cos(o * 0.92f + 0.4f))
                + (0.03f * (float) Math.sin(o * 1.35f + 1.1f));
           
            float jitter = 0.020f;
            x += rnd(-jitter, jitter);
            z += rnd(-jitter, jitter);
            y += rnd(-jitter * 0.55f, jitter * 0.55f);
           
            x = clamp(x, -0.46f, 0.46f);
            z = clamp(z, -0.36f, 0.36f);
            y = clamp(y, 0.36f, 0.82f);
           
            return new Vec3d(x, y, z);
        }
       
        private float getJitter(long now, int tid, boolean isYaw) {
            float amp = isYaw
                ? lerp(NOISE_YAW_MIN, NOISE_YAW_MAX, 0.5f)
                : lerp(NOISE_PITCH_MIN, NOISE_PITCH_MAX, 0.5f);
           
            float freq = lerp(NOISE_FREQ_MIN, NOISE_FREQ_MAX, 0.5f);
           
            float phase = isYaw ? noisePhaseYaw : noisePhasePitch;
            float tt = (float) ((now % 100000L) / 1000.0);
           
            float noise = perlin.fbm((tt * freq + phase), (float) (tid * 0.013 + 0.11), 4, 2.0f, 0.55f);
            float sway = perlin.noise((tt * 0.22f + phase * 0.07f), (float) (tid * 0.009 + 9.3));
           
            return (noise * 0.72f + sway * 0.28f) * amp;
        }
       
        public void reset() {
            noisePhaseYaw = rnd(0.0f, 999.0f);
            noisePhasePitch = rnd(0.0f, 999.0f);
            mpCurrent = Vec3d.ZERO;
            mpOrbit = 0.0f;
            mpLastUpdate = 0L;
            mpLastTargetId = Integer.MIN_VALUE;
            smoothedYaw = 0.0f;
            smoothedPitch = 0.0f;
            smoothLastTime = 0L;
            smoothTargetId = -1;
            targetLockTime = 0L;
            lastLockedTargetId = -1;
            currentSpeedMultiplier = 1.0f;
            savedViewValid = false;
            returnActive = false;
            overshootYaw = 0.0f;
            overshootPitch = 0.0f;
        }
       
        private float normalizeAngle(float angle) {
            angle = angle % 360.0F;
            if (angle >= 180.0F) angle -= 360.0F;
            if (angle < -180.0F) angle += 360.0F;
            return angle;
        }
       
        private static float clamp(float value, float min, float max) {
            if (value < min) return min;
            if (value > max) return max;
            return value;
        }
       
        private static double clamp(double value, double min, double max) {
            if (value < min) return min;
            if (value > max) return max;
            return value;
        }
       
        private static float lerp(float a, float b, float t) {
            return a + (b - a) * t;
        }
       
        private static double lerp(double a, double b, double t) {
            return a + (b - a) * t;
        }
    }
   
    private static RotatingHitbox instance;
   
    private final TargetFinder targetFinder = new TargetFinder();
    private final InternalFTSnapRotation ftSnapRotation = new InternalFTSnapRotation();
    private final SliderSetting attackRange = new SliderSetting(this, "Дистанция поиска")
        .min(1.0F).max(6.0F).step(0.1F).currentValue(3.5F);
   
    private final SliderSetting expandSize = new SliderSetting(this, "Размер увеличения")
        .min(0.1F).max(2.0F).step(0.1F).currentValue(0.5F);
   
    private final SelectSetting targetTypes = new SelectSetting(this, "Типы целей");
    private final SelectSetting.Value players = new SelectSetting.Value(targetTypes, "Players").select();
    private final SelectSetting.Value mobs = new SelectSetting.Value(targetTypes, "Mobs").select();
    private final SelectSetting.Value animals = new SelectSetting.Value(targetTypes, "Animals");
   
    private final BooleanSetting ignoreWalls = new BooleanSetting(this, "Игнорировать стены");
   
    private final BooleanSetting antiReach = new BooleanSetting(this, "Анти-Reach");
   
    private final SliderSetting antiReachDistance = new SliderSetting(this, "Дистанция Анти-Reach")
        .min(1.0F).max(3.0F).step(0.01F).currentValue(2.85F);
   
    private final BooleanSetting fakeSwing = new BooleanSetting(this, "Фейк свинг");
   
    private final BooleanSetting legitSprint = new BooleanSetting(this, "Легит спринт")
        .enable();
   
    private final BooleanSetting autoTargetESP = new BooleanSetting(this, "Авто TargetESP")
        .enable();
   
    private final SliderSetting lineWidth = new SliderSetting(this, "Толщина линий")
        .min(1.0F).max(5.0F).step(0.5F).currentValue(2.5F);
   
    private final ColorSetting hitboxColor = new ColorSetting(this, "Цвет хитбокса")
        .color(new ColorRGBA(100, 150, 255, 100));
   
    private final ColorSetting activeColor = new ColorSetting(this, "Цвет при активации")
        .color(new ColorRGBA(255, 50, 50, 120));
   
    private LivingEntity currentTarget = null;
    private boolean isAimingAtHitbox = false;
   
    private boolean sprintResetActive = false;
    private long sprintResetStartTime = 0;
    private static final long SPRINT_RESET_DURATION = 250;
   
    private final Map<Integer, Box> originalHitboxes = new HashMap<>();
   
    public RotatingHitbox() {
        instance = this;
    }
   
    public static RotatingHitbox getInstance() {
        return instance;
    }
   
    private final EventListener<ClientPlayerTickEvent> onTick = event -> {
        if (mc.player == null || mc.world == null) {
            resetState();
            return;
        }
       
        List<String> selectedTypes = targetTypes.getSelectedValues().stream()
            .map(SelectSetting.Value::getName)
            .toList();
       
        targetFinder.searchTargets(
            attackRange.getCurrentValue(),
            90.0f,
            ignoreWalls.isEnabled(),
            selectedTypes
        );
       
        targetFinder.validateTarget(target -> {
            if (target == null || !target.isAlive() || target.getHealth() <= 0) {
                return false;
            }
           
            float distance = mc.player.distanceTo(target);
            return distance <= attackRange.getCurrentValue();
        });
       
        LivingEntity previousTarget = currentTarget;
        currentTarget = targetFinder.getCurrentTarget();
       
        if (currentTarget != previousTarget) {
            ftSnapRotation.notifyTargetChanged(currentTarget);
        }
       
        if (currentTarget != null) {
            isAimingAtHitbox = isLookingAtExpandedHitbox();
           
            if (isAimingAtHitbox && !isAuraEnabled()) {
                ftSnapRotation.updateSavedView();
                ftSnapRotation.rotateTo(currentTarget, false);
               
                if (legitSprint.isEnabled()) {
                    handleLegitSprintReset();
                }
            }
           
            if (autoTargetESP.isEnabled()) {
                Holly.getInstance().getTargetManager().setCurrentTarget(currentTarget);
            }
        } else {
            sprintResetActive = false;
           
            if (autoTargetESP.isEnabled()) {
                Holly.getInstance().getTargetManager().setCurrentTarget(null);
            }
        }
    };
   
    private final EventListener<Render3DEvent> onRender3D = event -> {
        if (mc.player == null || mc.world == null) {
            return;
        }
       
        List<String> selectedTypes = targetTypes.getSelectedValues().stream()
            .map(SelectSetting.Value::getName)
            .toList();
       
        for (Entity entity : mc.world.getEntities()) {
            if (entity instanceof LivingEntity livingEntity && livingEntity != mc.player) {
                boolean isValidType = false;
                for (String type : selectedTypes) {
                    if (type.equals("Players") && livingEntity instanceof net.minecraft.entity.player.PlayerEntity) {
                        isValidType = true;
                        break;
                    } else if (type.equals("Mobs") && livingEntity instanceof net.minecraft.entity.mob.MobEntity) {
                        isValidType = true;
                        break;
                    } else if (type.equals("Animals") && livingEntity instanceof net.minecraft.entity.passive.AnimalEntity) {
                        isValidType = true;
                        break;
                    }
                }
               
                if (isValidType && livingEntity.isAlive()) {
                    int id = livingEntity.getId();
                   
                    if (!originalHitboxes.containsKey(id)) {
                        originalHitboxes.put(id, getOriginalHitbox(livingEntity));
                    }
                   
                    float radius = getEntityRadius(livingEntity);
                    float expandedRadius = radius + expandSize.getCurrentValue();
                    setEntityHitbox(livingEntity, expandedRadius);
                   
                    Box expandedBox = calculateExpandedHitbox(livingEntity);
                    boolean isCurrentTarget = (livingEntity == currentTarget && isAimingAtHitbox);
                    renderHitbox(event.getMatrices(), expandedBox, isCurrentTarget);
                }
            }
        }
    };
   
    private final EventListener<AttackEvent> onAttack = event -> {
        Entity target = event.getEntity();
       
        if (legitSprint.isEnabled() && target instanceof LivingEntity) {
            sprintResetActive = true;
            sprintResetStartTime = System.currentTimeMillis();
        }
       
        if (!antiReach.isEnabled() || mc.player == null) {
            return;
        }
       
        if (!(target instanceof LivingEntity livingEntity)) {
            return;
        }
       
        if (livingEntity == mc.player) {
            return;
        }
       
        Box originalBox = getOriginalHitbox(livingEntity);
        Vec3d eyes = mc.player.getEyePos();
        Vec3d closestPoint = getClosestPoint(eyes, originalBox);
        double distance = eyes.distanceTo(closestPoint);
       
        double maxDistance = antiReachDistance.getCurrentValue();
       
        if (distance > maxDistance) {
            event.cancel();
           
            if (fakeSwing.isEnabled() && mc.player != null) {
                mc.player.swingHand(net.minecraft.util.Hand.MAIN_HAND);
                mc.player.resetLastAttackedTicks();
            }
        }
    };
   
    private Box getOriginalHitbox(Entity entity) {
        return entity.getType().getDimensions().getBoxAt(entity.getPos());
    }
   
    private float getEntityRadius(Entity entity) {
        Box box = getOriginalHitbox(entity);
        return (float)(box.getLengthX() / 2.0);
    }
   
    private void setEntityHitbox(LivingEntity entity, float radius) {
        entity.setBoundingBox(
            new Box(
                entity.getX() - radius,
                entity.getBoundingBox().minY,
                entity.getZ() - radius,
                entity.getX() + radius,
                entity.getBoundingBox().maxY,
                entity.getZ() + radius
            )
        );
    }
   
    private Box calculateExpandedHitbox(LivingEntity target) {
        float radius = getEntityRadius(target);
        float expandedRadius = radius + expandSize.getCurrentValue();
       
        return new Box(
            target.getX() - expandedRadius,
            target.getBoundingBox().minY,
            target.getZ() - expandedRadius,
            target.getX() + expandedRadius,
            target.getBoundingBox().maxY,
            target.getZ() + expandedRadius
        );
    }
   
    private boolean isLookingAtExpandedHitbox() {
        if (mc.player == null || currentTarget == null) {
            return false;
        }
       
        float yaw = mc.player.getYaw();
        float pitch = mc.player.getPitch();
       
        float yawRad = (float) Math.toRadians(yaw);
        float pitchRad = (float) Math.toRadians(pitch);
       
        float x = (float)(-Math.sin(yawRad) * Math.cos(pitchRad));
        float y = (float)(-Math.sin(pitchRad));
        float z = (float)(Math.cos(yawRad) * Math.cos(pitchRad));
        Vec3d direction = new Vec3d(x, y, z);
       
        Vec3d eyes = mc.player.getEyePos();
       
        Box expandedBox = calculateExpandedHitbox(currentTarget);
       
        if (expandedBox.contains(eyes)) {
            return true;
        }
       
        Vec3d end = eyes.add(direction.multiply(attackRange.getCurrentValue() + 2.0));
        return expandedBox.raycast(eyes, end).isPresent();
    }
   
    private void resetState() {
        isAimingAtHitbox = false;
    }
   
    private void handleLegitSprintReset() {
        if (mc.player == null) return;
       
        long currentTime = System.currentTimeMillis();
       
        if (sprintResetActive) {
            mc.options.sprintKey.setPressed(false);
            mc.player.setSprinting(false);
           
            if (currentTime - sprintResetStartTime >= SPRINT_RESET_DURATION) {
                sprintResetActive = false;
            }
        }
    }
   
    private boolean isAuraEnabled() {
        return Holly.getInstance().getModuleManager().getModule(Aura.class).isEnabled();
    }
   
    private void restoreAllHitboxes() {
        if (mc.world == null) return;
       
        for (Entity entity : mc.world.getEntities()) {
            if (entity instanceof LivingEntity livingEntity && livingEntity != mc.player) {
                int id = livingEntity.getId();
                if (originalHitboxes.containsKey(id)) {
                    float radius = getEntityRadius(livingEntity);
                    setEntityHitbox(livingEntity, radius);
                }
            }
        }
       
        originalHitboxes.clear();
    }
   
    private Vec3d getClosestPoint(Vec3d point, Box box) {
        double x = Math.max(box.minX, Math.min(point.x, box.maxX));
        double y = Math.max(box.minY, Math.min(point.y, box.maxY));
        double z = Math.max(box.minZ, Math.min(point.z, box.maxZ));
        return new Vec3d(x, y, z);
    }
   
    private void renderHitbox(MatrixStack matrices, Box box, boolean active) {
        if (mc.player == null) return;
       
        matrices.push();
       
        RenderSystem.enableBlend();
        RenderSystem.defaultBlendFunc();
        RenderSystem.disableDepthTest();
        RenderSystem.disableCull();
        RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR);
        RenderSystem.lineWidth(lineWidth.getCurrentValue());
       
        Vec3d cameraPos = mc.gameRenderer.getCamera().getPos();
        matrices.translate(-cameraPos.x, -cameraPos.y, -cameraPos.z);
       
        ColorRGBA color = active ? activeColor.getColor() : hitboxColor.getColor();
       
        drawBoxFilled(matrices, box, color);
       
        ColorRGBA outlineColor = new ColorRGBA(
            Math.min(255, color.getRed() + 50),
            Math.min(255, color.getGreen() + 50),
            Math.min(255, color.getBlue() + 50),
            Math.min(255, color.getAlpha() + 80)
        );
        drawBoxOutline(matrices, box, outlineColor);
       
        RenderSystem.lineWidth(1.0f);
        RenderSystem.enableDepthTest();
        RenderSystem.enableCull();
        RenderSystem.disableBlend();
       
        matrices.pop();
    }
   
    private void drawBoxFilled(MatrixStack matrices, Box box, ColorRGBA color) {
        Matrix4f matrix = matrices.peek().getPositionMatrix();
       
        Tessellator tessellator = Tessellator.getInstance();
        BufferBuilder buffer = tessellator.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR);
       
        float r = color.getRed() / 255.0f;
        float g = color.getGreen() / 255.0f;
        float b = color.getBlue() / 255.0f;
        float a = color.getAlpha() / 255.0f * 0.5f;
       
        float minX = (float) box.minX;
        float minY = (float) box.minY;
        float minZ = (float) box.minZ;
        float maxX = (float) box.maxX;
        float maxY = (float) box.maxY;
        float maxZ = (float) box.maxZ;
       
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
       
        BufferRenderer.drawWithGlobalProgram(buffer.end());
    }
   
    private void drawBoxOutline(MatrixStack matrices, Box box, ColorRGBA color) {
        Matrix4f matrix = matrices.peek().getPositionMatrix();
       
        Tessellator tessellator = Tessellator.getInstance();
        BufferBuilder buffer = tessellator.begin(VertexFormat.DrawMode.DEBUG_LINES, VertexFormats.POSITION_COLOR);
       
        float r = color.getRed() / 255.0f;
        float g = color.getGreen() / 255.0f;
        float b = color.getBlue() / 255.0f;
        float a = color.getAlpha() / 255.0f;
       
        float minX = (float) box.minX;
        float minY = (float) box.minY;
        float minZ = (float) box.minZ;
        float maxX = (float) box.maxX;
        float maxY = (float) box.maxY;
        float maxZ = (float) box.maxZ;
       
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
       
        BufferRenderer.drawWithGlobalProgram(buffer.end());
    }
   
    @Override
    public void onEnable() {
        targetFinder.releaseTarget();
        currentTarget = null;
        isAimingAtHitbox = false;
        originalHitboxes.clear();
        ftSnapRotation.reset();
        sprintResetActive = false;
        sprintResetStartTime = 0;
    }
   
    @Override
    public void onDisable() {
        targetFinder.releaseTarget();
        currentTarget = null;
        isAimingAtHitbox = false;
        restoreAllHitboxes();
        ftSnapRotation.reset();
        sprintResetActive = false;
       
        if (autoTargetESP.isEnabled()) {
            Holly.getInstance().getTargetManager().setCurrentTarget(null);
        }
    }
   
    private static float rnd(float a, float b) {
        if (b <= a) return a;
        return a + ThreadLocalRandom.current().nextFloat() * (b - a);
    }
}
чёт не понял а в чём суть функции то?
 
Тебе надо было этот обход нурсултану продать а не сливать этой челяди!
Бро, код дефолтный,30 минут делал и не долго дорабатывал. Нурик сам напишет ток еще лучше если захочет
 
Всем привет, решил сделать снап хитбоксы под базу рокстара
В кратце эт не снапы а хиты с норм ротацией под фт, это не перенсос с система! ГПТ код имееться
Пожалуйста, авторизуйтесь для просмотра ссылки.

Java:
Expand Collapse Copy
package moscow.holly.systems.modules.modules.combat;

import com.mojang.blaze3d.systems.RenderSystem;
import moscow.holly.systems.event.EventListener;
import moscow.holly.systems.event.impl.game.AttackEvent;
import moscow.holly.systems.event.impl.player.ClientPlayerTickEvent;
import moscow.holly.systems.event.impl.render.Render3DEvent;
import moscow.holly.systems.modules.api.ModuleCategory;
import moscow.holly.systems.modules.api.ModuleInfo;
import moscow.holly.systems.modules.impl.BaseModule;
import moscow.holly.systems.setting.settings.BooleanSetting;
import moscow.holly.systems.setting.settings.ColorSetting;
import moscow.holly.systems.setting.settings.SelectSetting;
import moscow.holly.systems.setting.settings.SliderSetting;
import moscow.holly.Holly;
import moscow.holly.systems.modules.modules.combat.Aura;
import moscow.holly.utility.colors.ColorRGBA;
import moscow.holly.utility.combat.aura.TargetFinder;
import moscow.holly.utility.rotations.MoveCorrection;
import moscow.holly.utility.rotations.Rotation;
import moscow.holly.utility.rotations.RotationPriority;
import net.minecraft.client.gl.ShaderProgramKeys;
import net.minecraft.client.render.*;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
import org.joml.Matrix4f;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

@ModuleInfo(name = "Rotating Hitbox", category = ModuleCategory.COMBAT, desc = "Увеличенный хитбокс с ротацией как в Aura-Funtime")
public class RotatingHitbox extends BaseModule {
   
    private static class PerlinNoise {
        private final int[] p = new int[512];
       
        public PerlinNoise(int seed) {
            int[] perm = new int[256];
            for (int i = 0; i < 256; i++) perm[i] = i;
           
            Random r = new Random(seed);
            for (int i = 255; i > 0; i--) {
                int j = r.nextInt(i + 1);
                int t = perm[i];
                perm[i] = perm[j];
                perm[j] = t;
            }
           
            for (int i = 0; i < 256; i++) {
                int v = perm[i] & 255;
                p[i] = v;
                p[i + 256] = v;
            }
        }
       
        private static float fade(float t) {
            return t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f);
        }
       
        private static float lerp(float t, float a, float b) {
            return a + t * (b - a);
        }
       
        private static float grad(int hash, float x, float y, float z) {
            int h = hash & 15;
            float u = h < 8 ? x : y;
            float v = h < 4 ? y : (h == 12 || h == 14 ? x : z);
            return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
        }
       
        public float noise(float x, float y) {
            float z = 0.0f;
            int X = ((int) Math.floor(x)) & 255;
            int Y = ((int) Math.floor(y)) & 255;
            int Z = ((int) Math.floor(z)) & 255;
           
            x = (float) (x - Math.floor(x));
            y = (float) (y - Math.floor(y));
            z = (float) (z - Math.floor(z));
           
            float u = fade(x);
            float v = fade(y);
            float w = fade(z);
           
            int A = p[X] + Y;
            int AA = p[A] + Z;
            int AB = p[A + 1] + Z;
            int B = p[X + 1] + Y;
            int BA = p[B] + Z;
            int BB = p[B + 1] + Z;
           
            return lerp(w,
                lerp(v,
                    lerp(u, grad(p[AA], x, y, z), grad(p[BA], x - 1.0f, y, z)),
                    lerp(u, grad(p[AB], x, y - 1.0f, z), grad(p[BB], x - 1.0f, y - 1.0f, z))),
                lerp(v,
                    lerp(u, grad(p[AA + 1], x, y, z - 1.0f), grad(p[BA + 1], x - 1.0f, y, z - 1.0f)),
                    lerp(u, grad(p[AB + 1], x, y - 1.0f, z - 1.0f), grad(p[BB + 1], x - 1.0f, y - 1.0f, z - 1.0f))));
        }
       
        public float fbm(float x, float y, int octaves, float lacunarity, float gain) {
            float sum = 0.0f;
            float amp = 0.5f;
            float fx = x;
            float fy = y;
           
            for (int i = 0; i < octaves; i++) {
                sum += noise(fx, fy) * amp;
                fx *= lacunarity;
                fy *= lacunarity;
                amp *= gain;
            }
           
            return sum;
        }
    }
   
    private class InternalFTSnapRotation {
       
        private final PerlinNoise perlin = new PerlinNoise(1337);
       
        private static final float NOISE_YAW_MIN = 0.06f;
        private static final float NOISE_YAW_MAX = 0.38f;
        private static final float NOISE_PITCH_MIN = 0.04f;
        private static final float NOISE_PITCH_MAX = 0.22f;
        private static final float NOISE_FREQ_MIN = 0.55f;
        private static final float NOISE_FREQ_MAX = 1.65f;
       
        private float noisePhaseYaw = 0.0f;
        private float noisePhasePitch = 0.0f;
       
        private Vec3d mpCurrent = Vec3d.ZERO;
        private float mpOrbit = 0.0f;
        private long mpLastUpdate = 0L;
        private int mpLastTargetId = Integer.MIN_VALUE;
       
        private float critHeightOffset = 0.0f;
        private long lastAttackTime = 0L;
       
        private float overshootYaw = 0.0f;
        private float overshootPitch = 0.0f;
        private long overshootStartTime = 0L;
        private static final float OVERSHOOT_PROB = 0.25f;
        private static final float OVERSHOOT_MIN = 0.8f;
        private static final float OVERSHOOT_MAX = 2.5f;
        private static final long OVERSHOOT_DURATION = 80;
       
        private float smoothedYaw = 0.0f;
        private float smoothedPitch = 0.0f;
        private long smoothLastTime = 0L;
        private int smoothTargetId = -1;
        private long targetLockTime = 0L;
        private int lastLockedTargetId = -1;
        private float currentSpeedMultiplier = 1.0f;
       
        private boolean savedViewValid = false;
        private float savedYaw = 0.0f;
        private float savedPitch = 0.0f;
        private boolean returnActive = false;
        private long returnStartTime = 0L;
        private float returnYaw = 0.0f;
        private float returnPitch = 0.0f;
        public void notifyTargetChanged(LivingEntity newTarget) {
            if (newTarget == null) {
                lastLockedTargetId = -1;
                overshootYaw = 0.0f;
                overshootPitch = 0.0f;
                return;
            }
           
            int newId = newTarget.getId();
           
            if (lastLockedTargetId != newId) {
                lastLockedTargetId = newId;
                long now = System.currentTimeMillis();
                targetLockTime = now;
               
                currentSpeedMultiplier = rnd(0.65f, 0.95f);
               
                if (ThreadLocalRandom.current().nextFloat() < OVERSHOOT_PROB) {
                    overshootYaw = rnd(OVERSHOOT_MIN, OVERSHOOT_MAX) * (ThreadLocalRandom.current().nextBoolean() ? 1 : -1);
                    overshootPitch = rnd(OVERSHOOT_MIN * 0.6f, OVERSHOOT_MAX * 0.6f) * (ThreadLocalRandom.current().nextBoolean() ? 1 : -1);
                    overshootStartTime = now;
                } else {
                    overshootYaw = 0.0f;
                    overshootPitch = 0.0f;
                }
            }
        }
       
        public void updateSavedView() {
            if (mc.player == null) return;
           
            if (!savedViewValid) {
                savedViewValid = true;
                Rotation currentRotation = Holly.getInstance().getRotationHandler().getCurrentRotation();
                savedYaw = currentRotation.getYaw();
                savedPitch = currentRotation.getPitch();
            }
        }
       
        public void rotateTo(LivingEntity target, boolean attacking) {
            if (mc.player == null || target == null) return;
           
            updateSavedView();
           
            long now = System.currentTimeMillis();
            int tid = target.getId();
           
            if (smoothTargetId == -1) {
                Rotation currentRotation = Holly.getInstance().getRotationHandler().getCurrentRotation();
                smoothedYaw = currentRotation.getYaw();
                smoothedPitch = currentRotation.getPitch();
            }
           
            if (attacking && (now - lastAttackTime) > 400) {
                critHeightOffset = rnd(-0.15f, 0.15f);
                lastAttackTime = now;
            }
           
            float k = 0.035f;
            noisePhaseYaw += k * (0.65f + 0.35f * ((tid * 1103515245) & 255) / 255.0f);
            noisePhasePitch += k * (0.65f + 0.35f * ((tid * 1664525) & 255) / 255.0f);
           
            Vec3d targetPoint = getMultiPoint(target, attacking, now);
           
            Vec3d eyes = mc.player.getEyePos();
            Vec3d direction = targetPoint.subtract(eyes);
           
            double horizontalDistance = Math.sqrt(direction.x * direction.x + direction.z * direction.z);
           
            float targetYaw = (float) Math.toDegrees(Math.atan2(direction.z, direction.x)) - 90.0F;
            float targetPitch = (float) (-Math.toDegrees(Math.atan2(direction.y, horizontalDistance)));
           
            targetYaw = normalizeAngle(targetYaw);
            targetPitch = clamp(targetPitch, -90.0f, 90.0f);
           
            if (smoothTargetId != tid) {
                smoothTargetId = tid;
                smoothLastTime = now;
            }
           
            long dtMs = now - smoothLastTime;
            if (dtMs < 1) dtMs = 1;
            if (dtMs > 120) dtMs = 120;
            smoothLastTime = now;
           
            long timeSinceLock = now - targetLockTime;
            float lockProgress = Math.min(1.0f, timeSinceLock / 1000.0f);
           
            float speedMultiplier = lockProgress * lockProgress * (3.0f - 2.0f * lockProgress);
            speedMultiplier = 0.35f + speedMultiplier * 0.65f;
            speedMultiplier *= currentSpeedMultiplier;
           
            float baseYawSpeed = attacking ? 55.0f : 60.0f;
            float basePitchSpeed = attacking ? 44.0f : 48.0f;
           
            float yawSpeed = baseYawSpeed * speedMultiplier;
            float pitchSpeed = basePitchSpeed * speedMultiplier;
           
            float yawMaxDelta = yawSpeed * ((float) dtMs / 50.0f);
            float pitchMaxDelta = pitchSpeed * ((float) dtMs / 50.0f);
           
            float yawError = normalizeAngle(targetYaw - smoothedYaw);
            float pitchError = targetPitch - smoothedPitch;
           
            smoothedYaw += clamp(yawError, -yawMaxDelta, yawMaxDelta);
            smoothedPitch += clamp(pitchError, -pitchMaxDelta, pitchMaxDelta);
           
            smoothedYaw = normalizeAngle(smoothedYaw);
            smoothedPitch = clamp(smoothedPitch, -90.0f, 90.0f);
           
            float overshootFactor = 0.0f;
            if (overshootYaw != 0.0f || overshootPitch != 0.0f) {
                long timeSinceOvershoot = now - overshootStartTime;
                if (timeSinceOvershoot < OVERSHOOT_DURATION) {
                    overshootFactor = 1.0f - ((float) timeSinceOvershoot / OVERSHOOT_DURATION);
                    overshootFactor = overshootFactor * overshootFactor;
                } else {
                    overshootYaw = 0.0f;
                    overshootPitch = 0.0f;
                }
            }
           
            float jitterYaw = getJitter(now, tid, true);
            float jitterPitch = getJitter(now, tid, false);
           
            float finalYaw = smoothedYaw + jitterYaw + (overshootYaw * overshootFactor);
            float finalPitch = smoothedPitch + jitterPitch + (overshootPitch * overshootFactor);
           
            finalYaw = normalizeAngle(finalYaw);
            finalPitch = clamp(finalPitch, -90.0f, 90.0f);
           
            Rotation rotation = new Rotation(finalYaw, finalPitch);
            Holly.getInstance().getRotationHandler().rotate(
                rotation,
                MoveCorrection.SILENT,
                180.0f,
                180.0f,
                180.0f,
                RotationPriority.OVERRIDE
            );
        }
       
        private Vec3d getMultiPoint(LivingEntity target, boolean attacking, long now) {
            int tid = target.getId();
           
            if (tid != mpLastTargetId) {
                mpLastTargetId = tid;
                mpCurrent = Vec3d.ZERO;
                mpOrbit = rnd(0.0f, (float) (Math.PI * 2.0));
                mpLastUpdate = now;
            }
           
            long dtMs = now - mpLastUpdate;
            if (dtMs < 1) dtMs = 1;
            if (dtMs > 60) dtMs = 60;
            mpLastUpdate = now;
           
            float orbitSpeed = 0.36f;
            float dtScale = (float) dtMs / 50.0f;
            mpOrbit += orbitSpeed * dtScale + rnd(-0.018f, 0.018f) * dtScale;
           
            Vec3d desired = calculateOrbitPoint(mpOrbit, attacking);
           
            float tau = 120.0f;
            float alpha = (float) dtMs / tau;
            alpha = clamp(alpha, 0.0f, 1.0f);
            alpha = alpha * alpha * (3.0f - 2.0f * alpha);
           
            if (mpCurrent == Vec3d.ZERO) {
                mpCurrent = desired;
            } else {
                mpCurrent = new Vec3d(
                    lerp(mpCurrent.x, desired.x, alpha),
                    lerp(mpCurrent.y, desired.y, alpha),
                    lerp(mpCurrent.z, desired.z, alpha)
                );
            }
           
            Box box = target.getBoundingBox();
            double fx = 0.5 + mpCurrent.x * 0.5;
            double fy = mpCurrent.y;
            double fz = 0.5 + mpCurrent.z * 0.5;
           
            fx = clamp(fx, 0.0, 1.0);
            fy = clamp(fy, 0.36, 0.82);
            fz = clamp(fz, 0.0, 1.0);
           
            double x = box.minX + (box.maxX - box.minX) * fx;
            double y = box.minY + (box.maxY - box.minY) * fy;
            double z = box.minZ + (box.maxZ - box.minZ) * fz;
           
            return new Vec3d(
                clamp(x, box.minX + 1.0E-4, box.maxX - 1.0E-4),
                clamp(y, box.minY + 1.0E-4, box.maxY - 1.0E-4),
                clamp(z, box.minZ + 1.0E-4, box.maxZ - 1.0E-4)
            );
        }
       
        private Vec3d calculateOrbitPoint(float orbit, boolean attacking) {
            float o = orbit;
           
            float y = 0.56f
                + 0.10f * (float) Math.sin(o * 0.74f + 0.9f)
                + 0.06f * (float) Math.sin(o * 1.28f + 2.2f)
                - 0.05f * (float) (0.5 + 0.5 * Math.sin(o * 0.35f + 1.7f))
                + critHeightOffset;
           
            float x = (0.22f * (float) Math.sin(o))
                + (0.06f * (float) Math.sin(o * 1.85f + 0.25f));
           
            float z = (0.08f * (float) Math.cos(o * 0.92f + 0.4f))
                + (0.03f * (float) Math.sin(o * 1.35f + 1.1f));
           
            float jitter = 0.020f;
            x += rnd(-jitter, jitter);
            z += rnd(-jitter, jitter);
            y += rnd(-jitter * 0.55f, jitter * 0.55f);
           
            x = clamp(x, -0.46f, 0.46f);
            z = clamp(z, -0.36f, 0.36f);
            y = clamp(y, 0.36f, 0.82f);
           
            return new Vec3d(x, y, z);
        }
       
        private float getJitter(long now, int tid, boolean isYaw) {
            float amp = isYaw
                ? lerp(NOISE_YAW_MIN, NOISE_YAW_MAX, 0.5f)
                : lerp(NOISE_PITCH_MIN, NOISE_PITCH_MAX, 0.5f);
           
            float freq = lerp(NOISE_FREQ_MIN, NOISE_FREQ_MAX, 0.5f);
           
            float phase = isYaw ? noisePhaseYaw : noisePhasePitch;
            float tt = (float) ((now % 100000L) / 1000.0);
           
            float noise = perlin.fbm((tt * freq + phase), (float) (tid * 0.013 + 0.11), 4, 2.0f, 0.55f);
            float sway = perlin.noise((tt * 0.22f + phase * 0.07f), (float) (tid * 0.009 + 9.3));
           
            return (noise * 0.72f + sway * 0.28f) * amp;
        }
       
        public void reset() {
            noisePhaseYaw = rnd(0.0f, 999.0f);
            noisePhasePitch = rnd(0.0f, 999.0f);
            mpCurrent = Vec3d.ZERO;
            mpOrbit = 0.0f;
            mpLastUpdate = 0L;
            mpLastTargetId = Integer.MIN_VALUE;
            smoothedYaw = 0.0f;
            smoothedPitch = 0.0f;
            smoothLastTime = 0L;
            smoothTargetId = -1;
            targetLockTime = 0L;
            lastLockedTargetId = -1;
            currentSpeedMultiplier = 1.0f;
            savedViewValid = false;
            returnActive = false;
            overshootYaw = 0.0f;
            overshootPitch = 0.0f;
        }
       
        private float normalizeAngle(float angle) {
            angle = angle % 360.0F;
            if (angle >= 180.0F) angle -= 360.0F;
            if (angle < -180.0F) angle += 360.0F;
            return angle;
        }
       
        private static float clamp(float value, float min, float max) {
            if (value < min) return min;
            if (value > max) return max;
            return value;
        }
       
        private static double clamp(double value, double min, double max) {
            if (value < min) return min;
            if (value > max) return max;
            return value;
        }
       
        private static float lerp(float a, float b, float t) {
            return a + (b - a) * t;
        }
       
        private static double lerp(double a, double b, double t) {
            return a + (b - a) * t;
        }
    }
   
    private static RotatingHitbox instance;
   
    private final TargetFinder targetFinder = new TargetFinder();
    private final InternalFTSnapRotation ftSnapRotation = new InternalFTSnapRotation();
    private final SliderSetting attackRange = new SliderSetting(this, "Дистанция поиска")
        .min(1.0F).max(6.0F).step(0.1F).currentValue(3.5F);
   
    private final SliderSetting expandSize = new SliderSetting(this, "Размер увеличения")
        .min(0.1F).max(2.0F).step(0.1F).currentValue(0.5F);
   
    private final SelectSetting targetTypes = new SelectSetting(this, "Типы целей");
    private final SelectSetting.Value players = new SelectSetting.Value(targetTypes, "Players").select();
    private final SelectSetting.Value mobs = new SelectSetting.Value(targetTypes, "Mobs").select();
    private final SelectSetting.Value animals = new SelectSetting.Value(targetTypes, "Animals");
   
    private final BooleanSetting ignoreWalls = new BooleanSetting(this, "Игнорировать стены");
   
    private final BooleanSetting antiReach = new BooleanSetting(this, "Анти-Reach");
   
    private final SliderSetting antiReachDistance = new SliderSetting(this, "Дистанция Анти-Reach")
        .min(1.0F).max(3.0F).step(0.01F).currentValue(2.85F);
   
    private final BooleanSetting fakeSwing = new BooleanSetting(this, "Фейк свинг");
   
    private final BooleanSetting legitSprint = new BooleanSetting(this, "Легит спринт")
        .enable();
   
    private final BooleanSetting autoTargetESP = new BooleanSetting(this, "Авто TargetESP")
        .enable();
   
    private final SliderSetting lineWidth = new SliderSetting(this, "Толщина линий")
        .min(1.0F).max(5.0F).step(0.5F).currentValue(2.5F);
   
    private final ColorSetting hitboxColor = new ColorSetting(this, "Цвет хитбокса")
        .color(new ColorRGBA(100, 150, 255, 100));
   
    private final ColorSetting activeColor = new ColorSetting(this, "Цвет при активации")
        .color(new ColorRGBA(255, 50, 50, 120));
   
    private LivingEntity currentTarget = null;
    private boolean isAimingAtHitbox = false;
   
    private boolean sprintResetActive = false;
    private long sprintResetStartTime = 0;
    private static final long SPRINT_RESET_DURATION = 250;
   
    private final Map<Integer, Box> originalHitboxes = new HashMap<>();
   
    public RotatingHitbox() {
        instance = this;
    }
   
    public static RotatingHitbox getInstance() {
        return instance;
    }
   
    private final EventListener<ClientPlayerTickEvent> onTick = event -> {
        if (mc.player == null || mc.world == null) {
            resetState();
            return;
        }
       
        List<String> selectedTypes = targetTypes.getSelectedValues().stream()
            .map(SelectSetting.Value::getName)
            .toList();
       
        targetFinder.searchTargets(
            attackRange.getCurrentValue(),
            90.0f,
            ignoreWalls.isEnabled(),
            selectedTypes
        );
       
        targetFinder.validateTarget(target -> {
            if (target == null || !target.isAlive() || target.getHealth() <= 0) {
                return false;
            }
           
            float distance = mc.player.distanceTo(target);
            return distance <= attackRange.getCurrentValue();
        });
       
        LivingEntity previousTarget = currentTarget;
        currentTarget = targetFinder.getCurrentTarget();
       
        if (currentTarget != previousTarget) {
            ftSnapRotation.notifyTargetChanged(currentTarget);
        }
       
        if (currentTarget != null) {
            isAimingAtHitbox = isLookingAtExpandedHitbox();
           
            if (isAimingAtHitbox && !isAuraEnabled()) {
                ftSnapRotation.updateSavedView();
                ftSnapRotation.rotateTo(currentTarget, false);
               
                if (legitSprint.isEnabled()) {
                    handleLegitSprintReset();
                }
            }
           
            if (autoTargetESP.isEnabled()) {
                Holly.getInstance().getTargetManager().setCurrentTarget(currentTarget);
            }
        } else {
            sprintResetActive = false;
           
            if (autoTargetESP.isEnabled()) {
                Holly.getInstance().getTargetManager().setCurrentTarget(null);
            }
        }
    };
   
    private final EventListener<Render3DEvent> onRender3D = event -> {
        if (mc.player == null || mc.world == null) {
            return;
        }
       
        List<String> selectedTypes = targetTypes.getSelectedValues().stream()
            .map(SelectSetting.Value::getName)
            .toList();
       
        for (Entity entity : mc.world.getEntities()) {
            if (entity instanceof LivingEntity livingEntity && livingEntity != mc.player) {
                boolean isValidType = false;
                for (String type : selectedTypes) {
                    if (type.equals("Players") && livingEntity instanceof net.minecraft.entity.player.PlayerEntity) {
                        isValidType = true;
                        break;
                    } else if (type.equals("Mobs") && livingEntity instanceof net.minecraft.entity.mob.MobEntity) {
                        isValidType = true;
                        break;
                    } else if (type.equals("Animals") && livingEntity instanceof net.minecraft.entity.passive.AnimalEntity) {
                        isValidType = true;
                        break;
                    }
                }
               
                if (isValidType && livingEntity.isAlive()) {
                    int id = livingEntity.getId();
                   
                    if (!originalHitboxes.containsKey(id)) {
                        originalHitboxes.put(id, getOriginalHitbox(livingEntity));
                    }
                   
                    float radius = getEntityRadius(livingEntity);
                    float expandedRadius = radius + expandSize.getCurrentValue();
                    setEntityHitbox(livingEntity, expandedRadius);
                   
                    Box expandedBox = calculateExpandedHitbox(livingEntity);
                    boolean isCurrentTarget = (livingEntity == currentTarget && isAimingAtHitbox);
                    renderHitbox(event.getMatrices(), expandedBox, isCurrentTarget);
                }
            }
        }
    };
   
    private final EventListener<AttackEvent> onAttack = event -> {
        Entity target = event.getEntity();
       
        if (legitSprint.isEnabled() && target instanceof LivingEntity) {
            sprintResetActive = true;
            sprintResetStartTime = System.currentTimeMillis();
        }
       
        if (!antiReach.isEnabled() || mc.player == null) {
            return;
        }
       
        if (!(target instanceof LivingEntity livingEntity)) {
            return;
        }
       
        if (livingEntity == mc.player) {
            return;
        }
       
        Box originalBox = getOriginalHitbox(livingEntity);
        Vec3d eyes = mc.player.getEyePos();
        Vec3d closestPoint = getClosestPoint(eyes, originalBox);
        double distance = eyes.distanceTo(closestPoint);
       
        double maxDistance = antiReachDistance.getCurrentValue();
       
        if (distance > maxDistance) {
            event.cancel();
           
            if (fakeSwing.isEnabled() && mc.player != null) {
                mc.player.swingHand(net.minecraft.util.Hand.MAIN_HAND);
                mc.player.resetLastAttackedTicks();
            }
        }
    };
   
    private Box getOriginalHitbox(Entity entity) {
        return entity.getType().getDimensions().getBoxAt(entity.getPos());
    }
   
    private float getEntityRadius(Entity entity) {
        Box box = getOriginalHitbox(entity);
        return (float)(box.getLengthX() / 2.0);
    }
   
    private void setEntityHitbox(LivingEntity entity, float radius) {
        entity.setBoundingBox(
            new Box(
                entity.getX() - radius,
                entity.getBoundingBox().minY,
                entity.getZ() - radius,
                entity.getX() + radius,
                entity.getBoundingBox().maxY,
                entity.getZ() + radius
            )
        );
    }
   
    private Box calculateExpandedHitbox(LivingEntity target) {
        float radius = getEntityRadius(target);
        float expandedRadius = radius + expandSize.getCurrentValue();
       
        return new Box(
            target.getX() - expandedRadius,
            target.getBoundingBox().minY,
            target.getZ() - expandedRadius,
            target.getX() + expandedRadius,
            target.getBoundingBox().maxY,
            target.getZ() + expandedRadius
        );
    }
   
    private boolean isLookingAtExpandedHitbox() {
        if (mc.player == null || currentTarget == null) {
            return false;
        }
       
        float yaw = mc.player.getYaw();
        float pitch = mc.player.getPitch();
       
        float yawRad = (float) Math.toRadians(yaw);
        float pitchRad = (float) Math.toRadians(pitch);
       
        float x = (float)(-Math.sin(yawRad) * Math.cos(pitchRad));
        float y = (float)(-Math.sin(pitchRad));
        float z = (float)(Math.cos(yawRad) * Math.cos(pitchRad));
        Vec3d direction = new Vec3d(x, y, z);
       
        Vec3d eyes = mc.player.getEyePos();
       
        Box expandedBox = calculateExpandedHitbox(currentTarget);
       
        if (expandedBox.contains(eyes)) {
            return true;
        }
       
        Vec3d end = eyes.add(direction.multiply(attackRange.getCurrentValue() + 2.0));
        return expandedBox.raycast(eyes, end).isPresent();
    }
   
    private void resetState() {
        isAimingAtHitbox = false;
    }
   
    private void handleLegitSprintReset() {
        if (mc.player == null) return;
       
        long currentTime = System.currentTimeMillis();
       
        if (sprintResetActive) {
            mc.options.sprintKey.setPressed(false);
            mc.player.setSprinting(false);
           
            if (currentTime - sprintResetStartTime >= SPRINT_RESET_DURATION) {
                sprintResetActive = false;
            }
        }
    }
   
    private boolean isAuraEnabled() {
        return Holly.getInstance().getModuleManager().getModule(Aura.class).isEnabled();
    }
   
    private void restoreAllHitboxes() {
        if (mc.world == null) return;
       
        for (Entity entity : mc.world.getEntities()) {
            if (entity instanceof LivingEntity livingEntity && livingEntity != mc.player) {
                int id = livingEntity.getId();
                if (originalHitboxes.containsKey(id)) {
                    float radius = getEntityRadius(livingEntity);
                    setEntityHitbox(livingEntity, radius);
                }
            }
        }
       
        originalHitboxes.clear();
    }
   
    private Vec3d getClosestPoint(Vec3d point, Box box) {
        double x = Math.max(box.minX, Math.min(point.x, box.maxX));
        double y = Math.max(box.minY, Math.min(point.y, box.maxY));
        double z = Math.max(box.minZ, Math.min(point.z, box.maxZ));
        return new Vec3d(x, y, z);
    }
   
    private void renderHitbox(MatrixStack matrices, Box box, boolean active) {
        if (mc.player == null) return;
       
        matrices.push();
       
        RenderSystem.enableBlend();
        RenderSystem.defaultBlendFunc();
        RenderSystem.disableDepthTest();
        RenderSystem.disableCull();
        RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR);
        RenderSystem.lineWidth(lineWidth.getCurrentValue());
       
        Vec3d cameraPos = mc.gameRenderer.getCamera().getPos();
        matrices.translate(-cameraPos.x, -cameraPos.y, -cameraPos.z);
       
        ColorRGBA color = active ? activeColor.getColor() : hitboxColor.getColor();
       
        drawBoxFilled(matrices, box, color);
       
        ColorRGBA outlineColor = new ColorRGBA(
            Math.min(255, color.getRed() + 50),
            Math.min(255, color.getGreen() + 50),
            Math.min(255, color.getBlue() + 50),
            Math.min(255, color.getAlpha() + 80)
        );
        drawBoxOutline(matrices, box, outlineColor);
       
        RenderSystem.lineWidth(1.0f);
        RenderSystem.enableDepthTest();
        RenderSystem.enableCull();
        RenderSystem.disableBlend();
       
        matrices.pop();
    }
   
    private void drawBoxFilled(MatrixStack matrices, Box box, ColorRGBA color) {
        Matrix4f matrix = matrices.peek().getPositionMatrix();
       
        Tessellator tessellator = Tessellator.getInstance();
        BufferBuilder buffer = tessellator.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR);
       
        float r = color.getRed() / 255.0f;
        float g = color.getGreen() / 255.0f;
        float b = color.getBlue() / 255.0f;
        float a = color.getAlpha() / 255.0f * 0.5f;
       
        float minX = (float) box.minX;
        float minY = (float) box.minY;
        float minZ = (float) box.minZ;
        float maxX = (float) box.maxX;
        float maxY = (float) box.maxY;
        float maxZ = (float) box.maxZ;
       
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
       
        BufferRenderer.drawWithGlobalProgram(buffer.end());
    }
   
    private void drawBoxOutline(MatrixStack matrices, Box box, ColorRGBA color) {
        Matrix4f matrix = matrices.peek().getPositionMatrix();
       
        Tessellator tessellator = Tessellator.getInstance();
        BufferBuilder buffer = tessellator.begin(VertexFormat.DrawMode.DEBUG_LINES, VertexFormats.POSITION_COLOR);
       
        float r = color.getRed() / 255.0f;
        float g = color.getGreen() / 255.0f;
        float b = color.getBlue() / 255.0f;
        float a = color.getAlpha() / 255.0f;
       
        float minX = (float) box.minX;
        float minY = (float) box.minY;
        float minZ = (float) box.minZ;
        float maxX = (float) box.maxX;
        float maxY = (float) box.maxY;
        float maxZ = (float) box.maxZ;
       
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
       
        BufferRenderer.drawWithGlobalProgram(buffer.end());
    }
   
    @Override
    public void onEnable() {
        targetFinder.releaseTarget();
        currentTarget = null;
        isAimingAtHitbox = false;
        originalHitboxes.clear();
        ftSnapRotation.reset();
        sprintResetActive = false;
        sprintResetStartTime = 0;
    }
   
    @Override
    public void onDisable() {
        targetFinder.releaseTarget();
        currentTarget = null;
        isAimingAtHitbox = false;
        restoreAllHitboxes();
        ftSnapRotation.reset();
        sprintResetActive = false;
       
        if (autoTargetESP.isEnabled()) {
            Holly.getInstance().getTargetManager().setCurrentTarget(null);
        }
    }
   
    private static float rnd(float a, float b) {
        if (b <= a) return a;
        return a + ThreadLocalRandom.current().nextFloat() * (b - a);
    }
}
Ща полетят "легит" софты
 
Всем привет, решил сделать снап хитбоксы под базу рокстара
В кратце эт не снапы а хиты с норм ротацией под фт, это не перенсос с система! ГПТ код имееться
Пожалуйста, авторизуйтесь для просмотра ссылки.

Java:
Expand Collapse Copy
package moscow.holly.systems.modules.modules.combat;

import com.mojang.blaze3d.systems.RenderSystem;
import moscow.holly.systems.event.EventListener;
import moscow.holly.systems.event.impl.game.AttackEvent;
import moscow.holly.systems.event.impl.player.ClientPlayerTickEvent;
import moscow.holly.systems.event.impl.render.Render3DEvent;
import moscow.holly.systems.modules.api.ModuleCategory;
import moscow.holly.systems.modules.api.ModuleInfo;
import moscow.holly.systems.modules.impl.BaseModule;
import moscow.holly.systems.setting.settings.BooleanSetting;
import moscow.holly.systems.setting.settings.ColorSetting;
import moscow.holly.systems.setting.settings.SelectSetting;
import moscow.holly.systems.setting.settings.SliderSetting;
import moscow.holly.Holly;
import moscow.holly.systems.modules.modules.combat.Aura;
import moscow.holly.utility.colors.ColorRGBA;
import moscow.holly.utility.combat.aura.TargetFinder;
import moscow.holly.utility.rotations.MoveCorrection;
import moscow.holly.utility.rotations.Rotation;
import moscow.holly.utility.rotations.RotationPriority;
import net.minecraft.client.gl.ShaderProgramKeys;
import net.minecraft.client.render.*;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
import org.joml.Matrix4f;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

@ModuleInfo(name = "Rotating Hitbox", category = ModuleCategory.COMBAT, desc = "Увеличенный хитбокс с ротацией как в Aura-Funtime")
public class RotatingHitbox extends BaseModule {
   
    private static class PerlinNoise {
        private final int[] p = new int[512];
       
        public PerlinNoise(int seed) {
            int[] perm = new int[256];
            for (int i = 0; i < 256; i++) perm[i] = i;
           
            Random r = new Random(seed);
            for (int i = 255; i > 0; i--) {
                int j = r.nextInt(i + 1);
                int t = perm[i];
                perm[i] = perm[j];
                perm[j] = t;
            }
           
            for (int i = 0; i < 256; i++) {
                int v = perm[i] & 255;
                p[i] = v;
                p[i + 256] = v;
            }
        }
       
        private static float fade(float t) {
            return t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f);
        }
       
        private static float lerp(float t, float a, float b) {
            return a + t * (b - a);
        }
       
        private static float grad(int hash, float x, float y, float z) {
            int h = hash & 15;
            float u = h < 8 ? x : y;
            float v = h < 4 ? y : (h == 12 || h == 14 ? x : z);
            return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
        }
       
        public float noise(float x, float y) {
            float z = 0.0f;
            int X = ((int) Math.floor(x)) & 255;
            int Y = ((int) Math.floor(y)) & 255;
            int Z = ((int) Math.floor(z)) & 255;
           
            x = (float) (x - Math.floor(x));
            y = (float) (y - Math.floor(y));
            z = (float) (z - Math.floor(z));
           
            float u = fade(x);
            float v = fade(y);
            float w = fade(z);
           
            int A = p[X] + Y;
            int AA = p[A] + Z;
            int AB = p[A + 1] + Z;
            int B = p[X + 1] + Y;
            int BA = p[B] + Z;
            int BB = p[B + 1] + Z;
           
            return lerp(w,
                lerp(v,
                    lerp(u, grad(p[AA], x, y, z), grad(p[BA], x - 1.0f, y, z)),
                    lerp(u, grad(p[AB], x, y - 1.0f, z), grad(p[BB], x - 1.0f, y - 1.0f, z))),
                lerp(v,
                    lerp(u, grad(p[AA + 1], x, y, z - 1.0f), grad(p[BA + 1], x - 1.0f, y, z - 1.0f)),
                    lerp(u, grad(p[AB + 1], x, y - 1.0f, z - 1.0f), grad(p[BB + 1], x - 1.0f, y - 1.0f, z - 1.0f))));
        }
       
        public float fbm(float x, float y, int octaves, float lacunarity, float gain) {
            float sum = 0.0f;
            float amp = 0.5f;
            float fx = x;
            float fy = y;
           
            for (int i = 0; i < octaves; i++) {
                sum += noise(fx, fy) * amp;
                fx *= lacunarity;
                fy *= lacunarity;
                amp *= gain;
            }
           
            return sum;
        }
    }
   
    private class InternalFTSnapRotation {
       
        private final PerlinNoise perlin = new PerlinNoise(1337);
       
        private static final float NOISE_YAW_MIN = 0.06f;
        private static final float NOISE_YAW_MAX = 0.38f;
        private static final float NOISE_PITCH_MIN = 0.04f;
        private static final float NOISE_PITCH_MAX = 0.22f;
        private static final float NOISE_FREQ_MIN = 0.55f;
        private static final float NOISE_FREQ_MAX = 1.65f;
       
        private float noisePhaseYaw = 0.0f;
        private float noisePhasePitch = 0.0f;
       
        private Vec3d mpCurrent = Vec3d.ZERO;
        private float mpOrbit = 0.0f;
        private long mpLastUpdate = 0L;
        private int mpLastTargetId = Integer.MIN_VALUE;
       
        private float critHeightOffset = 0.0f;
        private long lastAttackTime = 0L;
       
        private float overshootYaw = 0.0f;
        private float overshootPitch = 0.0f;
        private long overshootStartTime = 0L;
        private static final float OVERSHOOT_PROB = 0.25f;
        private static final float OVERSHOOT_MIN = 0.8f;
        private static final float OVERSHOOT_MAX = 2.5f;
        private static final long OVERSHOOT_DURATION = 80;
       
        private float smoothedYaw = 0.0f;
        private float smoothedPitch = 0.0f;
        private long smoothLastTime = 0L;
        private int smoothTargetId = -1;
        private long targetLockTime = 0L;
        private int lastLockedTargetId = -1;
        private float currentSpeedMultiplier = 1.0f;
       
        private boolean savedViewValid = false;
        private float savedYaw = 0.0f;
        private float savedPitch = 0.0f;
        private boolean returnActive = false;
        private long returnStartTime = 0L;
        private float returnYaw = 0.0f;
        private float returnPitch = 0.0f;
        public void notifyTargetChanged(LivingEntity newTarget) {
            if (newTarget == null) {
                lastLockedTargetId = -1;
                overshootYaw = 0.0f;
                overshootPitch = 0.0f;
                return;
            }
           
            int newId = newTarget.getId();
           
            if (lastLockedTargetId != newId) {
                lastLockedTargetId = newId;
                long now = System.currentTimeMillis();
                targetLockTime = now;
               
                currentSpeedMultiplier = rnd(0.65f, 0.95f);
               
                if (ThreadLocalRandom.current().nextFloat() < OVERSHOOT_PROB) {
                    overshootYaw = rnd(OVERSHOOT_MIN, OVERSHOOT_MAX) * (ThreadLocalRandom.current().nextBoolean() ? 1 : -1);
                    overshootPitch = rnd(OVERSHOOT_MIN * 0.6f, OVERSHOOT_MAX * 0.6f) * (ThreadLocalRandom.current().nextBoolean() ? 1 : -1);
                    overshootStartTime = now;
                } else {
                    overshootYaw = 0.0f;
                    overshootPitch = 0.0f;
                }
            }
        }
       
        public void updateSavedView() {
            if (mc.player == null) return;
           
            if (!savedViewValid) {
                savedViewValid = true;
                Rotation currentRotation = Holly.getInstance().getRotationHandler().getCurrentRotation();
                savedYaw = currentRotation.getYaw();
                savedPitch = currentRotation.getPitch();
            }
        }
       
        public void rotateTo(LivingEntity target, boolean attacking) {
            if (mc.player == null || target == null) return;
           
            updateSavedView();
           
            long now = System.currentTimeMillis();
            int tid = target.getId();
           
            if (smoothTargetId == -1) {
                Rotation currentRotation = Holly.getInstance().getRotationHandler().getCurrentRotation();
                smoothedYaw = currentRotation.getYaw();
                smoothedPitch = currentRotation.getPitch();
            }
           
            if (attacking && (now - lastAttackTime) > 400) {
                critHeightOffset = rnd(-0.15f, 0.15f);
                lastAttackTime = now;
            }
           
            float k = 0.035f;
            noisePhaseYaw += k * (0.65f + 0.35f * ((tid * 1103515245) & 255) / 255.0f);
            noisePhasePitch += k * (0.65f + 0.35f * ((tid * 1664525) & 255) / 255.0f);
           
            Vec3d targetPoint = getMultiPoint(target, attacking, now);
           
            Vec3d eyes = mc.player.getEyePos();
            Vec3d direction = targetPoint.subtract(eyes);
           
            double horizontalDistance = Math.sqrt(direction.x * direction.x + direction.z * direction.z);
           
            float targetYaw = (float) Math.toDegrees(Math.atan2(direction.z, direction.x)) - 90.0F;
            float targetPitch = (float) (-Math.toDegrees(Math.atan2(direction.y, horizontalDistance)));
           
            targetYaw = normalizeAngle(targetYaw);
            targetPitch = clamp(targetPitch, -90.0f, 90.0f);
           
            if (smoothTargetId != tid) {
                smoothTargetId = tid;
                smoothLastTime = now;
            }
           
            long dtMs = now - smoothLastTime;
            if (dtMs < 1) dtMs = 1;
            if (dtMs > 120) dtMs = 120;
            smoothLastTime = now;
           
            long timeSinceLock = now - targetLockTime;
            float lockProgress = Math.min(1.0f, timeSinceLock / 1000.0f);
           
            float speedMultiplier = lockProgress * lockProgress * (3.0f - 2.0f * lockProgress);
            speedMultiplier = 0.35f + speedMultiplier * 0.65f;
            speedMultiplier *= currentSpeedMultiplier;
           
            float baseYawSpeed = attacking ? 55.0f : 60.0f;
            float basePitchSpeed = attacking ? 44.0f : 48.0f;
           
            float yawSpeed = baseYawSpeed * speedMultiplier;
            float pitchSpeed = basePitchSpeed * speedMultiplier;
           
            float yawMaxDelta = yawSpeed * ((float) dtMs / 50.0f);
            float pitchMaxDelta = pitchSpeed * ((float) dtMs / 50.0f);
           
            float yawError = normalizeAngle(targetYaw - smoothedYaw);
            float pitchError = targetPitch - smoothedPitch;
           
            smoothedYaw += clamp(yawError, -yawMaxDelta, yawMaxDelta);
            smoothedPitch += clamp(pitchError, -pitchMaxDelta, pitchMaxDelta);
           
            smoothedYaw = normalizeAngle(smoothedYaw);
            smoothedPitch = clamp(smoothedPitch, -90.0f, 90.0f);
           
            float overshootFactor = 0.0f;
            if (overshootYaw != 0.0f || overshootPitch != 0.0f) {
                long timeSinceOvershoot = now - overshootStartTime;
                if (timeSinceOvershoot < OVERSHOOT_DURATION) {
                    overshootFactor = 1.0f - ((float) timeSinceOvershoot / OVERSHOOT_DURATION);
                    overshootFactor = overshootFactor * overshootFactor;
                } else {
                    overshootYaw = 0.0f;
                    overshootPitch = 0.0f;
                }
            }
           
            float jitterYaw = getJitter(now, tid, true);
            float jitterPitch = getJitter(now, tid, false);
           
            float finalYaw = smoothedYaw + jitterYaw + (overshootYaw * overshootFactor);
            float finalPitch = smoothedPitch + jitterPitch + (overshootPitch * overshootFactor);
           
            finalYaw = normalizeAngle(finalYaw);
            finalPitch = clamp(finalPitch, -90.0f, 90.0f);
           
            Rotation rotation = new Rotation(finalYaw, finalPitch);
            Holly.getInstance().getRotationHandler().rotate(
                rotation,
                MoveCorrection.SILENT,
                180.0f,
                180.0f,
                180.0f,
                RotationPriority.OVERRIDE
            );
        }
       
        private Vec3d getMultiPoint(LivingEntity target, boolean attacking, long now) {
            int tid = target.getId();
           
            if (tid != mpLastTargetId) {
                mpLastTargetId = tid;
                mpCurrent = Vec3d.ZERO;
                mpOrbit = rnd(0.0f, (float) (Math.PI * 2.0));
                mpLastUpdate = now;
            }
           
            long dtMs = now - mpLastUpdate;
            if (dtMs < 1) dtMs = 1;
            if (dtMs > 60) dtMs = 60;
            mpLastUpdate = now;
           
            float orbitSpeed = 0.36f;
            float dtScale = (float) dtMs / 50.0f;
            mpOrbit += orbitSpeed * dtScale + rnd(-0.018f, 0.018f) * dtScale;
           
            Vec3d desired = calculateOrbitPoint(mpOrbit, attacking);
           
            float tau = 120.0f;
            float alpha = (float) dtMs / tau;
            alpha = clamp(alpha, 0.0f, 1.0f);
            alpha = alpha * alpha * (3.0f - 2.0f * alpha);
           
            if (mpCurrent == Vec3d.ZERO) {
                mpCurrent = desired;
            } else {
                mpCurrent = new Vec3d(
                    lerp(mpCurrent.x, desired.x, alpha),
                    lerp(mpCurrent.y, desired.y, alpha),
                    lerp(mpCurrent.z, desired.z, alpha)
                );
            }
           
            Box box = target.getBoundingBox();
            double fx = 0.5 + mpCurrent.x * 0.5;
            double fy = mpCurrent.y;
            double fz = 0.5 + mpCurrent.z * 0.5;
           
            fx = clamp(fx, 0.0, 1.0);
            fy = clamp(fy, 0.36, 0.82);
            fz = clamp(fz, 0.0, 1.0);
           
            double x = box.minX + (box.maxX - box.minX) * fx;
            double y = box.minY + (box.maxY - box.minY) * fy;
            double z = box.minZ + (box.maxZ - box.minZ) * fz;
           
            return new Vec3d(
                clamp(x, box.minX + 1.0E-4, box.maxX - 1.0E-4),
                clamp(y, box.minY + 1.0E-4, box.maxY - 1.0E-4),
                clamp(z, box.minZ + 1.0E-4, box.maxZ - 1.0E-4)
            );
        }
       
        private Vec3d calculateOrbitPoint(float orbit, boolean attacking) {
            float o = orbit;
           
            float y = 0.56f
                + 0.10f * (float) Math.sin(o * 0.74f + 0.9f)
                + 0.06f * (float) Math.sin(o * 1.28f + 2.2f)
                - 0.05f * (float) (0.5 + 0.5 * Math.sin(o * 0.35f + 1.7f))
                + critHeightOffset;
           
            float x = (0.22f * (float) Math.sin(o))
                + (0.06f * (float) Math.sin(o * 1.85f + 0.25f));
           
            float z = (0.08f * (float) Math.cos(o * 0.92f + 0.4f))
                + (0.03f * (float) Math.sin(o * 1.35f + 1.1f));
           
            float jitter = 0.020f;
            x += rnd(-jitter, jitter);
            z += rnd(-jitter, jitter);
            y += rnd(-jitter * 0.55f, jitter * 0.55f);
           
            x = clamp(x, -0.46f, 0.46f);
            z = clamp(z, -0.36f, 0.36f);
            y = clamp(y, 0.36f, 0.82f);
           
            return new Vec3d(x, y, z);
        }
       
        private float getJitter(long now, int tid, boolean isYaw) {
            float amp = isYaw
                ? lerp(NOISE_YAW_MIN, NOISE_YAW_MAX, 0.5f)
                : lerp(NOISE_PITCH_MIN, NOISE_PITCH_MAX, 0.5f);
           
            float freq = lerp(NOISE_FREQ_MIN, NOISE_FREQ_MAX, 0.5f);
           
            float phase = isYaw ? noisePhaseYaw : noisePhasePitch;
            float tt = (float) ((now % 100000L) / 1000.0);
           
            float noise = perlin.fbm((tt * freq + phase), (float) (tid * 0.013 + 0.11), 4, 2.0f, 0.55f);
            float sway = perlin.noise((tt * 0.22f + phase * 0.07f), (float) (tid * 0.009 + 9.3));
           
            return (noise * 0.72f + sway * 0.28f) * amp;
        }
       
        public void reset() {
            noisePhaseYaw = rnd(0.0f, 999.0f);
            noisePhasePitch = rnd(0.0f, 999.0f);
            mpCurrent = Vec3d.ZERO;
            mpOrbit = 0.0f;
            mpLastUpdate = 0L;
            mpLastTargetId = Integer.MIN_VALUE;
            smoothedYaw = 0.0f;
            smoothedPitch = 0.0f;
            smoothLastTime = 0L;
            smoothTargetId = -1;
            targetLockTime = 0L;
            lastLockedTargetId = -1;
            currentSpeedMultiplier = 1.0f;
            savedViewValid = false;
            returnActive = false;
            overshootYaw = 0.0f;
            overshootPitch = 0.0f;
        }
       
        private float normalizeAngle(float angle) {
            angle = angle % 360.0F;
            if (angle >= 180.0F) angle -= 360.0F;
            if (angle < -180.0F) angle += 360.0F;
            return angle;
        }
       
        private static float clamp(float value, float min, float max) {
            if (value < min) return min;
            if (value > max) return max;
            return value;
        }
       
        private static double clamp(double value, double min, double max) {
            if (value < min) return min;
            if (value > max) return max;
            return value;
        }
       
        private static float lerp(float a, float b, float t) {
            return a + (b - a) * t;
        }
       
        private static double lerp(double a, double b, double t) {
            return a + (b - a) * t;
        }
    }
   
    private static RotatingHitbox instance;
   
    private final TargetFinder targetFinder = new TargetFinder();
    private final InternalFTSnapRotation ftSnapRotation = new InternalFTSnapRotation();
    private final SliderSetting attackRange = new SliderSetting(this, "Дистанция поиска")
        .min(1.0F).max(6.0F).step(0.1F).currentValue(3.5F);
   
    private final SliderSetting expandSize = new SliderSetting(this, "Размер увеличения")
        .min(0.1F).max(2.0F).step(0.1F).currentValue(0.5F);
   
    private final SelectSetting targetTypes = new SelectSetting(this, "Типы целей");
    private final SelectSetting.Value players = new SelectSetting.Value(targetTypes, "Players").select();
    private final SelectSetting.Value mobs = new SelectSetting.Value(targetTypes, "Mobs").select();
    private final SelectSetting.Value animals = new SelectSetting.Value(targetTypes, "Animals");
   
    private final BooleanSetting ignoreWalls = new BooleanSetting(this, "Игнорировать стены");
   
    private final BooleanSetting antiReach = new BooleanSetting(this, "Анти-Reach");
   
    private final SliderSetting antiReachDistance = new SliderSetting(this, "Дистанция Анти-Reach")
        .min(1.0F).max(3.0F).step(0.01F).currentValue(2.85F);
   
    private final BooleanSetting fakeSwing = new BooleanSetting(this, "Фейк свинг");
   
    private final BooleanSetting legitSprint = new BooleanSetting(this, "Легит спринт")
        .enable();
   
    private final BooleanSetting autoTargetESP = new BooleanSetting(this, "Авто TargetESP")
        .enable();
   
    private final SliderSetting lineWidth = new SliderSetting(this, "Толщина линий")
        .min(1.0F).max(5.0F).step(0.5F).currentValue(2.5F);
   
    private final ColorSetting hitboxColor = new ColorSetting(this, "Цвет хитбокса")
        .color(new ColorRGBA(100, 150, 255, 100));
   
    private final ColorSetting activeColor = new ColorSetting(this, "Цвет при активации")
        .color(new ColorRGBA(255, 50, 50, 120));
   
    private LivingEntity currentTarget = null;
    private boolean isAimingAtHitbox = false;
   
    private boolean sprintResetActive = false;
    private long sprintResetStartTime = 0;
    private static final long SPRINT_RESET_DURATION = 250;
   
    private final Map<Integer, Box> originalHitboxes = new HashMap<>();
   
    public RotatingHitbox() {
        instance = this;
    }
   
    public static RotatingHitbox getInstance() {
        return instance;
    }
   
    private final EventListener<ClientPlayerTickEvent> onTick = event -> {
        if (mc.player == null || mc.world == null) {
            resetState();
            return;
        }
       
        List<String> selectedTypes = targetTypes.getSelectedValues().stream()
            .map(SelectSetting.Value::getName)
            .toList();
       
        targetFinder.searchTargets(
            attackRange.getCurrentValue(),
            90.0f,
            ignoreWalls.isEnabled(),
            selectedTypes
        );
       
        targetFinder.validateTarget(target -> {
            if (target == null || !target.isAlive() || target.getHealth() <= 0) {
                return false;
            }
           
            float distance = mc.player.distanceTo(target);
            return distance <= attackRange.getCurrentValue();
        });
       
        LivingEntity previousTarget = currentTarget;
        currentTarget = targetFinder.getCurrentTarget();
       
        if (currentTarget != previousTarget) {
            ftSnapRotation.notifyTargetChanged(currentTarget);
        }
       
        if (currentTarget != null) {
            isAimingAtHitbox = isLookingAtExpandedHitbox();
           
            if (isAimingAtHitbox && !isAuraEnabled()) {
                ftSnapRotation.updateSavedView();
                ftSnapRotation.rotateTo(currentTarget, false);
               
                if (legitSprint.isEnabled()) {
                    handleLegitSprintReset();
                }
            }
           
            if (autoTargetESP.isEnabled()) {
                Holly.getInstance().getTargetManager().setCurrentTarget(currentTarget);
            }
        } else {
            sprintResetActive = false;
           
            if (autoTargetESP.isEnabled()) {
                Holly.getInstance().getTargetManager().setCurrentTarget(null);
            }
        }
    };
   
    private final EventListener<Render3DEvent> onRender3D = event -> {
        if (mc.player == null || mc.world == null) {
            return;
        }
       
        List<String> selectedTypes = targetTypes.getSelectedValues().stream()
            .map(SelectSetting.Value::getName)
            .toList();
       
        for (Entity entity : mc.world.getEntities()) {
            if (entity instanceof LivingEntity livingEntity && livingEntity != mc.player) {
                boolean isValidType = false;
                for (String type : selectedTypes) {
                    if (type.equals("Players") && livingEntity instanceof net.minecraft.entity.player.PlayerEntity) {
                        isValidType = true;
                        break;
                    } else if (type.equals("Mobs") && livingEntity instanceof net.minecraft.entity.mob.MobEntity) {
                        isValidType = true;
                        break;
                    } else if (type.equals("Animals") && livingEntity instanceof net.minecraft.entity.passive.AnimalEntity) {
                        isValidType = true;
                        break;
                    }
                }
               
                if (isValidType && livingEntity.isAlive()) {
                    int id = livingEntity.getId();
                   
                    if (!originalHitboxes.containsKey(id)) {
                        originalHitboxes.put(id, getOriginalHitbox(livingEntity));
                    }
                   
                    float radius = getEntityRadius(livingEntity);
                    float expandedRadius = radius + expandSize.getCurrentValue();
                    setEntityHitbox(livingEntity, expandedRadius);
                   
                    Box expandedBox = calculateExpandedHitbox(livingEntity);
                    boolean isCurrentTarget = (livingEntity == currentTarget && isAimingAtHitbox);
                    renderHitbox(event.getMatrices(), expandedBox, isCurrentTarget);
                }
            }
        }
    };
   
    private final EventListener<AttackEvent> onAttack = event -> {
        Entity target = event.getEntity();
       
        if (legitSprint.isEnabled() && target instanceof LivingEntity) {
            sprintResetActive = true;
            sprintResetStartTime = System.currentTimeMillis();
        }
       
        if (!antiReach.isEnabled() || mc.player == null) {
            return;
        }
       
        if (!(target instanceof LivingEntity livingEntity)) {
            return;
        }
       
        if (livingEntity == mc.player) {
            return;
        }
       
        Box originalBox = getOriginalHitbox(livingEntity);
        Vec3d eyes = mc.player.getEyePos();
        Vec3d closestPoint = getClosestPoint(eyes, originalBox);
        double distance = eyes.distanceTo(closestPoint);
       
        double maxDistance = antiReachDistance.getCurrentValue();
       
        if (distance > maxDistance) {
            event.cancel();
           
            if (fakeSwing.isEnabled() && mc.player != null) {
                mc.player.swingHand(net.minecraft.util.Hand.MAIN_HAND);
                mc.player.resetLastAttackedTicks();
            }
        }
    };
   
    private Box getOriginalHitbox(Entity entity) {
        return entity.getType().getDimensions().getBoxAt(entity.getPos());
    }
   
    private float getEntityRadius(Entity entity) {
        Box box = getOriginalHitbox(entity);
        return (float)(box.getLengthX() / 2.0);
    }
   
    private void setEntityHitbox(LivingEntity entity, float radius) {
        entity.setBoundingBox(
            new Box(
                entity.getX() - radius,
                entity.getBoundingBox().minY,
                entity.getZ() - radius,
                entity.getX() + radius,
                entity.getBoundingBox().maxY,
                entity.getZ() + radius
            )
        );
    }
   
    private Box calculateExpandedHitbox(LivingEntity target) {
        float radius = getEntityRadius(target);
        float expandedRadius = radius + expandSize.getCurrentValue();
       
        return new Box(
            target.getX() - expandedRadius,
            target.getBoundingBox().minY,
            target.getZ() - expandedRadius,
            target.getX() + expandedRadius,
            target.getBoundingBox().maxY,
            target.getZ() + expandedRadius
        );
    }
   
    private boolean isLookingAtExpandedHitbox() {
        if (mc.player == null || currentTarget == null) {
            return false;
        }
       
        float yaw = mc.player.getYaw();
        float pitch = mc.player.getPitch();
       
        float yawRad = (float) Math.toRadians(yaw);
        float pitchRad = (float) Math.toRadians(pitch);
       
        float x = (float)(-Math.sin(yawRad) * Math.cos(pitchRad));
        float y = (float)(-Math.sin(pitchRad));
        float z = (float)(Math.cos(yawRad) * Math.cos(pitchRad));
        Vec3d direction = new Vec3d(x, y, z);
       
        Vec3d eyes = mc.player.getEyePos();
       
        Box expandedBox = calculateExpandedHitbox(currentTarget);
       
        if (expandedBox.contains(eyes)) {
            return true;
        }
       
        Vec3d end = eyes.add(direction.multiply(attackRange.getCurrentValue() + 2.0));
        return expandedBox.raycast(eyes, end).isPresent();
    }
   
    private void resetState() {
        isAimingAtHitbox = false;
    }
   
    private void handleLegitSprintReset() {
        if (mc.player == null) return;
       
        long currentTime = System.currentTimeMillis();
       
        if (sprintResetActive) {
            mc.options.sprintKey.setPressed(false);
            mc.player.setSprinting(false);
           
            if (currentTime - sprintResetStartTime >= SPRINT_RESET_DURATION) {
                sprintResetActive = false;
            }
        }
    }
   
    private boolean isAuraEnabled() {
        return Holly.getInstance().getModuleManager().getModule(Aura.class).isEnabled();
    }
   
    private void restoreAllHitboxes() {
        if (mc.world == null) return;
       
        for (Entity entity : mc.world.getEntities()) {
            if (entity instanceof LivingEntity livingEntity && livingEntity != mc.player) {
                int id = livingEntity.getId();
                if (originalHitboxes.containsKey(id)) {
                    float radius = getEntityRadius(livingEntity);
                    setEntityHitbox(livingEntity, radius);
                }
            }
        }
       
        originalHitboxes.clear();
    }
   
    private Vec3d getClosestPoint(Vec3d point, Box box) {
        double x = Math.max(box.minX, Math.min(point.x, box.maxX));
        double y = Math.max(box.minY, Math.min(point.y, box.maxY));
        double z = Math.max(box.minZ, Math.min(point.z, box.maxZ));
        return new Vec3d(x, y, z);
    }
   
    private void renderHitbox(MatrixStack matrices, Box box, boolean active) {
        if (mc.player == null) return;
       
        matrices.push();
       
        RenderSystem.enableBlend();
        RenderSystem.defaultBlendFunc();
        RenderSystem.disableDepthTest();
        RenderSystem.disableCull();
        RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR);
        RenderSystem.lineWidth(lineWidth.getCurrentValue());
       
        Vec3d cameraPos = mc.gameRenderer.getCamera().getPos();
        matrices.translate(-cameraPos.x, -cameraPos.y, -cameraPos.z);
       
        ColorRGBA color = active ? activeColor.getColor() : hitboxColor.getColor();
       
        drawBoxFilled(matrices, box, color);
       
        ColorRGBA outlineColor = new ColorRGBA(
            Math.min(255, color.getRed() + 50),
            Math.min(255, color.getGreen() + 50),
            Math.min(255, color.getBlue() + 50),
            Math.min(255, color.getAlpha() + 80)
        );
        drawBoxOutline(matrices, box, outlineColor);
       
        RenderSystem.lineWidth(1.0f);
        RenderSystem.enableDepthTest();
        RenderSystem.enableCull();
        RenderSystem.disableBlend();
       
        matrices.pop();
    }
   
    private void drawBoxFilled(MatrixStack matrices, Box box, ColorRGBA color) {
        Matrix4f matrix = matrices.peek().getPositionMatrix();
       
        Tessellator tessellator = Tessellator.getInstance();
        BufferBuilder buffer = tessellator.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR);
       
        float r = color.getRed() / 255.0f;
        float g = color.getGreen() / 255.0f;
        float b = color.getBlue() / 255.0f;
        float a = color.getAlpha() / 255.0f * 0.5f;
       
        float minX = (float) box.minX;
        float minY = (float) box.minY;
        float minZ = (float) box.minZ;
        float maxX = (float) box.maxX;
        float maxY = (float) box.maxY;
        float maxZ = (float) box.maxZ;
       
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
       
        BufferRenderer.drawWithGlobalProgram(buffer.end());
    }
   
    private void drawBoxOutline(MatrixStack matrices, Box box, ColorRGBA color) {
        Matrix4f matrix = matrices.peek().getPositionMatrix();
       
        Tessellator tessellator = Tessellator.getInstance();
        BufferBuilder buffer = tessellator.begin(VertexFormat.DrawMode.DEBUG_LINES, VertexFormats.POSITION_COLOR);
       
        float r = color.getRed() / 255.0f;
        float g = color.getGreen() / 255.0f;
        float b = color.getBlue() / 255.0f;
        float a = color.getAlpha() / 255.0f;
       
        float minX = (float) box.minX;
        float minY = (float) box.minY;
        float minZ = (float) box.minZ;
        float maxX = (float) box.maxX;
        float maxY = (float) box.maxY;
        float maxZ = (float) box.maxZ;
       
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a);
       
        buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a);
       
        buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a);
        buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a);
       
        BufferRenderer.drawWithGlobalProgram(buffer.end());
    }
   
    @Override
    public void onEnable() {
        targetFinder.releaseTarget();
        currentTarget = null;
        isAimingAtHitbox = false;
        originalHitboxes.clear();
        ftSnapRotation.reset();
        sprintResetActive = false;
        sprintResetStartTime = 0;
    }
   
    @Override
    public void onDisable() {
        targetFinder.releaseTarget();
        currentTarget = null;
        isAimingAtHitbox = false;
        restoreAllHitboxes();
        ftSnapRotation.reset();
        sprintResetActive = false;
       
        if (autoTargetESP.isEnabled()) {
            Holly.getInstance().getTargetManager().setCurrentTarget(null);
        }
    }
   
    private static float rnd(float a, float b) {
        if (b <= a) return a;
        return a + ThreadLocalRandom.current().nextFloat() * (b - a);
    }
}
блять что туда запихано в 1к строчек, это можно за 300-400 строчек написать
 
Назад
Сверху Снизу