Начинающий
- Статус
- Оффлайн
- Регистрация
- 12 Янв 2026
- Сообщения
- 8
- Реакции
- 0
Ситуация такая , что удары по хитбоксам(увеличенной части) нормально проходят только при фрилук или ф5 , а от 1 лица не идут чё за хуня
Java:
package zov.polyak.module.list.combat;
import com.google.common.eventbus.Subscribe;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.AxeItem;
import net.minecraft.item.ItemStack;
import net.minecraft.item.MaceItem;
import net.minecraft.item.SwordItem;
import net.minecraft.item.TridentItem;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import zov.polyak.event.EventGameUpdate;
import zov.polyak.event.list.EventAttack;
import zov.polyak.event.list.EventTick;
import zov.polyak.event.list.EventUseItem;
import zov.polyak.module.Module;
import zov.polyak.module.ModuleCategory;
import zov.polyak.module.ModuleInformation;
import zov.polyak.module.settings.BooleanSetting;
import zov.polyak.module.settings.ModeSetting;
import zov.polyak.module.settings.SliderSetting;
import zov.polyak.util.friend.FriendRepository;
import zov.polyak.util.rotation.FreeLookComponent;
import zov.polyak.util.rotation.Rotation;
import zov.polyak.util.rotation.RotationComponent;
import java.util.concurrent.ThreadLocalRandom;
@ModuleInformation(
moduleName = "Hitbox",
moduleDesc = "Увеличивает размер хитбокса игрока",
moduleCategory = ModuleCategory.COMBAT
)
public class Hitbox extends Module {
private static final String ROTATION_DEFAULT = "Обычная";
private static final String ROTATION_NEW = "Новая";
private static final String TARGET_PLAYERS = "Игроки";
private static final String TARGET_MOBS = "Мобы";
private static final String TARGET_ALL = "Все";
private static final float VANILLA_SIZE = 0.3F;
private static final double EXTRA_VERTICAL_RAY = 0.5;
private static final long NANOS_PER_SECOND = 1_000_000_000L;
/* === Настройки === */
private final ModeSetting targets = new ModeSetting(
"Цели", TARGET_PLAYERS, TARGET_PLAYERS, TARGET_MOBS, TARGET_ALL
);
private final BooleanSetting onlyWithWeapon = new BooleanSetting("Только с оружием", true);
private final BooleanSetting onlyArmored = new BooleanSetting("Только в броне", false);
private final BooleanSetting onlyTarget = new BooleanSetting("Только на противнике", false);
private final SliderSetting resetTime = new SliderSetting("Время сброса", 3.0, 1.0, 7.0, 0.5)
.setVisible(onlyTarget::getValue);
private final BooleanSetting invisibleHitbox = new BooleanSetting("Невидимый хитбокс", false);
private final BooleanSetting fixedSize = new BooleanSetting("Фиксированный размер", true);
private final SliderSetting fixedSizeValue = new SliderSetting("Фикс. размер", 0.7, 0.3, 1.2, 0.05)
.setVisible(fixedSize::getValue);
private final SliderSetting minSize = new SliderSetting("Мин. размер", 0.3, 0.2, 1.0, 0.05)
.setVisible(() -> !fixedSize.getValue());
private final SliderSetting maxSize = new SliderSetting("Макс. размер", 2.0, 0.5, 5.0, 0.1)
.setVisible(() -> !fixedSize.getValue());
private final SliderSetting step = new SliderSetting("Шаг", 0.1, 0.05, 0.5, 0.05)
.setVisible(() -> !fixedSize.getValue());
private final SliderSetting size = new SliderSetting("Размер", 0.3, 0.3, 5.0, 0.05)
.setVisible(() -> !fixedSize.getValue());
private final BooleanSetting animation = new BooleanSetting("Анимация", true);
private final SliderSetting animationSpeed = new SliderSetting("Скорость анимации", 6.0, 1.0, 15.0, 0.5)
.setVisible(animation::getValue);
private final BooleanSetting bypass = new BooleanSetting("Обход", true);
private final ModeSetting rotationMode = new ModeSetting("Ротация", ROTATION_NEW, ROTATION_DEFAULT, ROTATION_NEW)
.setVisible(bypass::getValue);
private final BooleanSetting antiReach = new BooleanSetting("Anti-Reach", true)
.setVisible(bypass::getValue);
private final SliderSetting antiReachDistance = new SliderSetting("Дистанция Anti-Reach", 2.85, 1.0, 3.0, 0.01)
.setVisible(() -> bypass.getValue() && antiReach.getValue());
private final BooleanSetting fakeSwing = new BooleanSetting("Фейк свинг", true)
.setVisible(bypass::getValue);
private final SliderSetting searchDistance = new SliderSetting("Дистанция", 5.0, 3.0, 10.0, 0.5)
.setVisible(bypass::getValue);
private final SliderSetting aimSpeed = new SliderSetting("Скорость наводки", 0.85, 0.1, 2.0, 0.05)
.setVisible(bypass::getValue);
private final SliderSetting trackingSpeed = new SliderSetting("Скорость слежения", 0.85, 0.1, 2.0, 0.05)
.setVisible(bypass::getValue);
/* === Состояние === */
private final boolean clientLook = false;
private double lastVariableSize = VANILLA_SIZE;
private LivingEntity rotationTarget;
private Vec3d aimPoint;
private LivingEntity onlyTargetEntity;
private long onlyTargetTime;
private boolean usingItem;
private float currentYaw;
private float currentPitch;
private boolean hasRotation;
private boolean rotating;
private boolean fastAimPhase;
private boolean verticalAim;
private float animatedSize = VANILLA_SIZE;
private long lastAnimationTime;
private long rotationDeltaTime;
private long targetStartTime;
private long returnStartTime;
private LivingEntity previousTarget;
private boolean returning;
private LivingEntity queuedSnapAttackTarget;
private int queuedSnapAttackTicks;
private boolean ignoreAttackEvent;
/* === Жизненный цикл === */
@Override
public void onEnable() {
super.onEnable();
if (fixedSize.getValue()) {
size.setValue(fixedSizeValue.getValue());
} else {
size.setValue(lastVariableSize);
}
animatedSize = VANILLA_SIZE;
lastAnimationTime = System.nanoTime();
applyHitboxes();
clearQueuedSnapAttack();
ignoreAttackEvent = false;
resetRotation();
}
@Override
public void onDisable() {
size.setValue(VANILLA_SIZE);
animatedSize = VANILLA_SIZE;
resetAllBoxes();
clearQueuedSnapAttack();
ignoreAttackEvent = false;
resetRotation();
super.onDisable();
}
/* === Tick: бокс + анимация === */
@Subscribe
private void onTick(EventTick event) {
if (mc.player == null || mc.world == null) return;
updateAnimation();
updateOnlyTarget();
applyHitboxes();
processQueuedSnapAttack();
}
/* === GameUpdate: bypass-ротация === */
@Subscribe
private void onGameUpdate(EventGameUpdate event) {
if (mc.player == null || mc.world == null) return;
applyHitboxes();
// Игрок использует предмет — временно сбрасываем размер до vanilla.
if (mc.player.isUsingItem() && !usingItem) {
usingItem = true;
if (!fixedSize.getValue()) {
lastVariableSize = size.getValue();
}
size.setValue(VANILLA_SIZE);
} else if (!mc.player.isUsingItem() && usingItem) {
usingItem = false;
double restore = fixedSize.getValue() ? fixedSizeValue.getValue() : lastVariableSize;
size.setValue(restore);
}
float currentSize = size.getFloatValue();
if (currentSize <= VANILLA_SIZE) {
if (rotating) returnToCamera();
return;
}
if (!bypass.getValue()) {
returnToCamera();
return;
}
if (onlyWithWeapon.getValue() && !hasWeapon()) {
returnToCamera();
return;
}
LivingEntity target = findTarget();
if (target == null) {
returnToCamera();
return;
}
boolean expandedHit = isLookingAtBox(target, true, false);
if (ROTATION_NEW.equals(rotationMode.getValue()) && !expandedHit) {
expandedHit = isLookingAtBox(target, true, true);
}
if (!expandedHit) {
returnToCamera();
return;
}
boolean realHit = isLookingAtBox(target, false, false);
if (realHit && !rotating) {
returnToCamera();
return;
}
boolean verticalOutside = isVerticalOutside(target);
rotationTarget = target;
rotating = true;
if (!hasRotation) {
currentYaw = mc.player.getYaw();
currentPitch = mc.player.getPitch();
hasRotation = true;
fastAimPhase = true;
}
if (previousTarget != target) {
previousTarget = target;
targetStartTime = System.currentTimeMillis();
fastAimPhase = true;
}
if (verticalOutside) {
Vec3d edge = getVerticalEdgePoint(target);
if (edge != null) {
aimPoint = edge;
verticalAim = true;
} else {
aimPoint = getDefaultAimPoint(target);
verticalAim = false;
}
} else {
aimPoint = getDefaultAimPoint(target);
verticalAim = false;
}
if (ROTATION_NEW.equals(rotationMode.getValue())) {
updateNewRotation(aimPoint);
} else {
updateDefaultRotation(aimPoint);
}
returning = false;
applyRotation();
}
/* === Атака: only-target + AntiReach === */
@Subscribe
private void onAttack(EventAttack event) {
if (mc.player == null || mc.world == null) return;
if (ignoreAttackEvent) {
ignoreAttackEvent = false;
return;
}
if (!(event.getEntity() instanceof LivingEntity living)) return;
if (!isTargetEntity(living)) return;
if (bypass.getValue()
&& ROTATION_NEW.equals(rotationMode.getValue())
&& size.getFloatValue() > VANILLA_SIZE) {
boolean realHit = isLookingAtBox(living, false, false);
boolean expandedHit = isLookingAtBox(living, true, true);
if (expandedHit && !realHit) {
event.cancelEvent();
queueSnapAttack(living);
return;
}
}
// Запоминаем последнего ударенного
if (onlyTarget.getValue()) {
onlyTargetEntity = living;
onlyTargetTime = System.currentTimeMillis();
}
if (antiReach.getValue() && shouldCancelByAntiReach(living)) {
event.cancelEvent();
doFakeSwing();
}
}
/* === Использование предмета: AntiReach + cancel в новом режиме === */
@Subscribe
private void onUseItem(EventUseItem event) {
if (mc.player == null || mc.world == null) return;
HitResult hitResult = event.getTarget();
if (!(hitResult instanceof EntityHitResult entityHit)) return;
if (!(entityHit.getEntity() instanceof LivingEntity living)) return;
if (!isTargetEntity(living)) return;
if (onlyTarget.getValue() && isWithinTarget(living)) {
onlyTargetEntity = living;
onlyTargetTime = System.currentTimeMillis();
}
// В новой ротации режем удар по entity, в которого попали только из-за расширения
if (bypass.getValue()
&& ROTATION_NEW.equals(rotationMode.getValue())
&& size.getFloatValue() > VANILLA_SIZE) {
boolean realHit = isLookingAtBox(living, false, false);
boolean expandedHit = isLookingAtBox(living, true, true);
if (expandedHit && !realHit) {
event.cancelEvent();
queueSnapAttack(living);
return;
}
}
if (antiReach.getValue() && shouldCancelByAntiReach(living)) {
event.cancelEvent();
doFakeSwing();
}
}
/* === Расширение хитбоксов === */
private void applyHitboxes() {
if (mc.world == null || mc.player == null) return;
float currentSize = size.getFloatValue();
for (Entity entity : mc.world.getEntities()) {
if (entity instanceof LivingEntity living && living != mc.player) {
if (isValidBypassTarget(living) && isWithinTarget(living) && currentSize > VANILLA_SIZE) {
living.setBoundingBox(getExpandedBox(living));
} else {
resetBox(living);
}
}
}
}
private float getCurrentExpandRadius(LivingEntity living) {
float baseRadius = getBaseRadius(living);
if (invisibleHitbox.getValue()) return baseRadius;
float visualSize = animation.getValue() ? animatedSize : size.getFloatValue();
return baseRadius + (visualSize - VANILLA_SIZE);
}
/* === Анимация === */
private void updateAnimation() {
long now = System.nanoTime();
if (lastAnimationTime == 0L || now - lastAnimationTime > NANOS_PER_SECOND) {
lastAnimationTime = now;
return;
}
float dt = (float) (now - lastAnimationTime) / NANOS_PER_SECOND;
lastAnimationTime = now;
float target = invisibleHitbox.getValue() ? VANILLA_SIZE : size.getFloatValue();
float diff = target - animatedSize;
if (Math.abs(diff) > 0.001F) {
float speed = animationSpeed.getFloatValue();
float k = 1.0F - (float) Math.exp(-dt * speed);
animatedSize += diff * k;
} else {
animatedSize = target;
}
}
/* === Only-target reset === */
private void updateOnlyTarget() {
if (!onlyTarget.getValue() || onlyTargetEntity == null) return;
long elapsed = System.currentTimeMillis() - onlyTargetTime;
long limit = (long) (resetTime.getValue() * 1000.0);
if (elapsed >= limit) {
onlyTargetEntity = null;
onlyTargetTime = 0L;
}
}
private boolean isWithinTarget(LivingEntity living) {
return !onlyTarget.getValue() || living == onlyTargetEntity;
}
/* === Поиск цели === */
private LivingEntity findTarget() {
LivingEntity best = null;
double bestDistance = searchDistance.getValue();
for (Entity entity : mc.world.getEntities()) {
if (!(entity instanceof LivingEntity living)) continue;
if (living == mc.player) continue;
if (!isValidBypassTarget(living)) continue;
if (!isWithinTarget(living)) continue;
double distance = mc.player.distanceTo(living);
if (distance >= bestDistance) continue;
bestDistance = distance;
best = living;
}
return best;
}
private boolean isValidBypassTarget(LivingEntity living) {
if (!living.isAlive()) return false;
if (!isTargetEntity(living)) return false;
if (living instanceof PlayerEntity player) {
if (player.isSpectator()) return false;
if (!FriendRepository.shouldAttack(player)) return false;
if (onlyArmored.getValue() && !hasArmor(player)) return false;
}
return true;
}
/* === Обычная ротация === */
private void updateDefaultRotation(Vec3d point) {
float targetYaw = getYawTo(point);
float targetPitch = getPitchTo(point);
float yawDiff = Math.abs(wrapDegrees(targetYaw - currentYaw));
if (yawDiff > 2.0F) {
fastAimPhase = true;
currentYaw = lerpAngle(currentYaw, targetYaw, aimSpeed.getValue());
} else {
fastAimPhase = false;
currentYaw = lerpAngle(currentYaw, targetYaw, trackingSpeed.getValue());
}
if (verticalAim) {
float pitchDiff = Math.abs(targetPitch - currentPitch);
if (pitchDiff > 2.0F) {
currentPitch = lerpPitch(currentPitch, targetPitch, aimSpeed.getValue());
} else {
currentPitch = lerpPitch(currentPitch, targetPitch, trackingSpeed.getValue());
}
} else {
float playerPitch = mc.player.getPitch();
float pitchDiff = Math.abs(playerPitch - currentPitch);
if (pitchDiff > 1.0F) {
currentPitch = lerpPitch(currentPitch, playerPitch, aimSpeed.getValue());
} else {
currentPitch = playerPitch;
}
}
}
/* === Новая ротация === */
private void updateNewRotation(Vec3d point) {
long now = System.nanoTime();
double dt = rotationDeltaTime > 0L ? (now - rotationDeltaTime) / 16_666_666.7 : 1.0;
dt = MathHelper.clamp(dt, 0.05, 3.0);
rotationDeltaTime = now;
if (rotationTarget != previousTarget) {
previousTarget = rotationTarget;
targetStartTime = System.currentTimeMillis();
}
float targetYaw = getYawTo(point);
float targetPitch = verticalAim ? getPitchTo(point) : mc.player.getPitch();
double yawDelta = wrapDegrees(targetYaw - currentYaw);
double pitchDelta = targetPitch - currentPitch;
double distance = Math.sqrt(yawDelta * yawDelta + pitchDelta * pitchDelta);
if (distance < 0.05) return;
fastAimPhase = distance > 2.0;
double speed = fastAimPhase ? aimSpeed.getValue() : trackingSpeed.getValue();
double reaction = MathHelper.clamp((System.currentTimeMillis() - targetStartTime) / 200.0, 0.0, 1.0);
double smoothReaction = reaction * reaction * (3.0 - 2.0 * reaction);
double distanceFactor = MathHelper.clamp(distance / 15.0, 0.15, 1.0);
double rng = 0.9 + ThreadLocalRandom.current().nextDouble(0.2);
double mult = speed * smoothReaction * distanceFactor * dt * rng;
double yawStep = yawDelta * mult;
double pitchStep = pitchDelta * mult;
double gcd = getGcd();
yawStep = applyStepGcd(yawStep, gcd);
pitchStep = applyStepGcd(pitchStep, gcd);
if (yawStep == 0.0 && Math.abs(yawDelta) > gcd) yawStep = Math.signum(yawDelta) * gcd;
if (pitchStep == 0.0 && Math.abs(pitchDelta) > gcd) pitchStep = Math.signum(pitchDelta) * gcd;
if (Math.abs(yawStep) > Math.abs(yawDelta)) yawStep = applyStepGcd(yawDelta, gcd);
if (Math.abs(pitchStep) > Math.abs(pitchDelta)) pitchStep = applyStepGcd(pitchDelta, gcd);
currentYaw += (float) yawStep;
currentPitch = MathHelper.clamp(currentPitch + (float) pitchStep, -90.0F, 90.0F);
}
/* === Возврат камеры === */
private void returnToCamera() {
if (!hasRotation || mc.player == null) {
resetRotation();
return;
}
if (!returning) {
returning = true;
returnStartTime = System.currentTimeMillis();
}
float playerYaw = mc.player.getYaw();
float playerPitch = mc.player.getPitch();
float yawDelta = Math.abs(wrapDegrees(currentYaw - playerYaw));
float pitchDelta = Math.abs(currentPitch - playerPitch);
if (ROTATION_NEW.equals(rotationMode.getValue())) {
updateReturnNew(playerYaw, playerPitch);
} else {
currentYaw = lerpAngle(currentYaw, playerYaw, aimSpeed.getValue());
currentPitch = lerpPitch(currentPitch, playerPitch, aimSpeed.getValue());
}
applyRotation();
if (yawDelta < 5.0F && pitchDelta < 5.0F) {
resetRotation();
}
}
private void updateReturnNew(float playerYaw, float playerPitch) {
long now = System.nanoTime();
double dt = rotationDeltaTime > 0L ? (now - rotationDeltaTime) / 16_666_666.7 : 1.0;
dt = MathHelper.clamp(dt, 0.05, 3.0);
rotationDeltaTime = now;
double yawDelta = wrapDegrees(playerYaw - currentYaw);
double pitchDelta = playerPitch - currentPitch;
double distance = Math.sqrt(yawDelta * yawDelta + pitchDelta * pitchDelta);
if (distance < 0.05) return;
double speed = aimSpeed.getValue();
double reaction = MathHelper.clamp((System.currentTimeMillis() - returnStartTime) / 200.0, 0.0, 1.0);
double smoothReaction = reaction * reaction * (3.0 - 2.0 * reaction);
double distanceFactor = MathHelper.clamp(distance / 15.0, 0.15, 1.0);
double rng = 0.9 + ThreadLocalRandom.current().nextDouble(0.2);
double mult = speed * smoothReaction * distanceFactor * dt * rng;
double yawStep = yawDelta * mult;
double pitchStep = pitchDelta * mult;
double gcd = getGcd();
yawStep = applyStepGcd(yawStep, gcd);
pitchStep = applyStepGcd(pitchStep, gcd);
if (yawStep == 0.0 && Math.abs(yawDelta) > gcd) yawStep = Math.signum(yawDelta) * gcd;
if (pitchStep == 0.0 && Math.abs(pitchDelta) > gcd) pitchStep = Math.signum(pitchDelta) * gcd;
currentYaw += (float) yawStep;
currentPitch = MathHelper.clamp(currentPitch + (float) pitchStep, -90.0F, 90.0F);
}
/* === AntiReach === */
private boolean shouldCancelByAntiReach(LivingEntity target) {
if (size.getFloatValue() <= VANILLA_SIZE) return false;
Box realBox = getDefaultBox(target);
Vec3d eye = mc.player.getEyePos();
Vec3d nearest = clampToBox(eye, realBox);
return eye.distanceTo(nearest) > antiReachDistance.getValue();
}
/* === Raytrace === */
private Vec3d getMouseLookVec() {
if (FreeLookComponent.isActive()) {
float f = FreeLookComponent.getFreePitch() * 0.017453292F;
float g = -FreeLookComponent.getFreeYaw() * 0.017453292F;
float h = MathHelper.cos(g);
float i = MathHelper.sin(g);
float j = MathHelper.cos(f);
float k = MathHelper.sin(f);
return new Vec3d((double) (i * j), (double) (-k), (double) (h * j));
}
return mc.player.getRotationVec(1.0F);
}
private boolean isLookingAtBox(LivingEntity target, boolean expanded, boolean addVertical) {
Vec3d eye = mc.player.getEyePos();
Vec3d look = getMouseLookVec();
Vec3d end = eye.add(look.multiply(searchDistance.getValue()));
Box box = expanded ? getExpandedBox(target) : getDefaultBox(target);
if (addVertical) {
box = box.expand(0.0, EXTRA_VERTICAL_RAY, 0.0);
}
if (box.contains(eye)) {
double dx = target.getX() - eye.x;
double dz = target.getZ() - eye.z;
double lx = look.x;
double lz = look.z;
double horiz = Math.sqrt(dx * dx + dz * dz);
double lookHoriz = Math.sqrt(lx * lx + lz * lz);
if (horiz < 0.01 || lookHoriz < 0.01) return true;
double dot = (dx / horiz) * (lx / lookHoriz) + (dz / horiz) * (lz / lookHoriz);
return dot > -0.5;
}
return box.raycast(eye, end).isPresent();
}
private Vec3d getDefaultAimPoint(LivingEntity target) {
Vec3d eye = mc.player.getEyePos();
Vec3d look = mc.player.getRotationVec(1.0F);
Vec3d end = eye.add(look.multiply(searchDistance.getValue()));
Box realBox = getDefaultBox(target);
Box safe = new Box(
realBox.minX + 0.2, realBox.minY,
realBox.minZ + 0.2, realBox.maxX - 0.2,
realBox.maxY, realBox.maxZ - 0.2
);
Box expanded = getExpandedBox(target);
Vec3d projected = expanded.raycast(eye, end).orElse(expanded.getCenter());
return clampToBox(projected, safe);
}
private boolean isVerticalOutside(LivingEntity target) {
Vec3d eye = mc.player.getEyePos();
Box box = getDefaultBox(target);
double y = projectVerticalIntersection(target, eye, mc.player.getPitch());
return y < box.minY || y > box.maxY;
}
private Vec3d getVerticalEdgePoint(LivingEntity target) {
Vec3d eye = mc.player.getEyePos();
Box box = getDefaultBox(target);
double y = projectVerticalIntersection(target, eye, mc.player.getPitch());
double picked;
if (y < box.minY) {
picked = box.minY + 0.1;
} else if (y > box.maxY) {
picked = box.maxY - 0.1;
} else {
return null;
}
return new Vec3d(target.getX(), picked, target.getZ());
}
private double projectVerticalIntersection(LivingEntity target, Vec3d eye, float pitch) {
double dx = target.getX() - eye.x;
double dz = target.getZ() - eye.z;
double horiz = Math.sqrt(dx * dx + dz * dz);
double rad = Math.toRadians(pitch);
return horiz < 0.5 ? eye.y - Math.tan(rad) * 0.5 : eye.y - Math.tan(rad) * horiz;
}
/* === Боксы === */
private Box getDefaultBox(Entity entity) {
return entity.getType().getDimensions().getBoxAt(entity.getPos());
}
private Box getExpandedBox(Entity entity) {
float radius = getBaseRadius(entity) + Math.max(0.0F, size.getFloatValue() - VANILLA_SIZE);
return buildBoxAround(entity, radius);
}
private Box buildBoxAround(Entity entity, float radius) {
return new Box(
entity.getX() - radius,
entity.getY(),
entity.getZ() - radius,
entity.getX() + radius,
entity.getY() + entity.getHeight(),
entity.getZ() + radius
);
}
private float getBaseRadius(Entity entity) {
return (float) (getDefaultBox(entity).getLengthX() / 2.0);
}
private void resetBox(LivingEntity entity) {
entity.setBoundingBox(getDefaultBox(entity));
}
private void resetAllBoxes() {
if (mc.world == null || mc.player == null) return;
for (Entity entity : mc.world.getEntities()) {
if (entity instanceof LivingEntity living && living != mc.player) {
resetBox(living);
}
}
}
/* === Цели === */
private boolean isTargetEntity(Entity entity) {
if (TARGET_ALL.equals(targets.getValue())) return entity instanceof LivingEntity;
if (TARGET_PLAYERS.equals(targets.getValue())) return entity instanceof PlayerEntity;
if (TARGET_MOBS.equals(targets.getValue())) return entity instanceof MobEntity;
return false;
}
/* === Оружие / броня === */
private boolean hasWeapon() {
if (mc.player == null) return false;
return isWeapon(mc.player.getMainHandStack()) || isWeapon(mc.player.getOffHandStack());
}
private boolean isWeapon(ItemStack stack) {
if (stack == null || stack.isEmpty()) return false;
return stack.getItem() instanceof SwordItem
|| stack.getItem() instanceof AxeItem
|| stack.getItem() instanceof TridentItem
|| stack.getItem() instanceof MaceItem;
}
private boolean hasArmor(PlayerEntity player) {
return !player.getInventory().armor.get(0).isEmpty()
|| !player.getInventory().armor.get(1).isEmpty()
|| !player.getInventory().armor.get(2).isEmpty()
|| !player.getInventory().armor.get(3).isEmpty();
}
/* === Ротация / геометрия === */
private float getYawTo(Vec3d point) {
Vec3d eye = mc.player.getEyePos();
Vec3d adj = point;
if (rotationTarget != null) {
adj = adj.add(rotationTarget.getVelocity().multiply(0.1));
}
double dx = adj.x - eye.x;
double dz = adj.z - eye.z;
return (float) Math.toDegrees(Math.atan2(dz, dx)) - 90.0F;
}
private float getPitchTo(Vec3d point) {
Vec3d eye = mc.player.getEyePos();
double dx = point.x - eye.x;
double dy = point.y - eye.y;
double dz = point.z - eye.z;
double horiz = Math.sqrt(dx * dx + dz * dz);
return (float) -Math.toDegrees(Math.atan2(dy, horiz));
}
private float lerpAngle(float from, float to, double speed) {
return from + wrapDegrees(to - from) * (float) speed;
}
private float lerpPitch(float from, float to, double speed) {
return MathHelper.clamp(from + (to - from) * (float) speed, -90.0F, 90.0F);
}
private static float wrapDegrees(float value) {
return ((value + 180.0F) % 360.0F + 360.0F) % 360.0F - 180.0F;
}
private static double wrapDegrees(double value) {
value %= 360.0;
if (value > 180.0) value -= 360.0;
if (value < -180.0) value += 360.0;
return value;
}
private double getGcd() {
double sens = mc.options.getMouseSensitivity().getValue();
double f = sens * 0.6 + 0.2;
return f * f * f * 1.2;
}
private double applyStepGcd(double value, double gcd) {
return gcd <= 1.0E-4 ? value : value - value % gcd;
}
private Vec3d clampToBox(Vec3d point, Box box) {
return new Vec3d(
Math.max(box.minX, Math.min(point.x, box.maxX)),
Math.max(box.minY, Math.min(point.y, box.maxY)),
Math.max(box.minZ, Math.min(point.z, box.maxZ))
);
}
private void applyRotation() {
RotationComponent.update(
new Rotation(currentYaw, currentPitch),
360, 360, 360, 360, 0, 1, clientLook
);
}
private void snapToTarget(LivingEntity target) {
rotationTarget = target;
Vec3d point;
if (isVerticalOutside(target)) {
Vec3d edge = getVerticalEdgePoint(target);
point = edge != null ? edge : getDefaultAimPoint(target);
} else {
point = getDefaultAimPoint(target);
}
currentYaw = getYawTo(point);
currentPitch = MathHelper.clamp(getPitchTo(point), -90.0F, 90.0F);
hasRotation = true;
rotating = true;
returning = false;
applyRotation();
}
private void queueSnapAttack(LivingEntity target) {
snapToTarget(target);
// Выполняем удар сразу же, чтобы не было задержки в 1 тик.
// Это поможет, если цель быстро движется.
ignoreAttackEvent = true;
if (mc.interactionManager != null && mc.player != null) {
mc.interactionManager.attackEntity(mc.player, target);
mc.player.swingHand(Hand.MAIN_HAND);
}
}
private void processQueuedSnapAttack() {
// Метод оставлен для совместимости, но теперь атака происходит мгновенно в queueSnapAttack
clearQueuedSnapAttack();
}
private void clearQueuedSnapAttack() {
queuedSnapAttackTarget = null;
queuedSnapAttackTicks = 0;
}
private void doFakeSwing() {
if (!fakeSwing.getValue() || mc.player == null) return;
mc.player.swingHand(Hand.MAIN_HAND);
mc.player.resetLastAttackedTicks();
}
private void resetRotation() {
rotationTarget = null;
aimPoint = null;
previousTarget = null;
hasRotation = false;
rotating = false;
fastAimPhase = false;
verticalAim = false;
returning = false;
currentYaw = 0.0F;
currentPitch = 0.0F;
rotationDeltaTime = 0L;
targetStartTime = 0L;
returnStartTime = 0L;
}
}
Последнее редактирование: