package im.expensive.modules.impl.combat;
import com.google.common.eventbus.Subscribe;
import im.expensive.commandstorage.FriendStorage;
import im.expensive.events.EventMotion;
import im.expensive.events.EventMove;
import im.expensive.modules.api.Category;
import im.expensive.modules.api.Module;
import im.expensive.modules.api.ModuleRegister;
import im.expensive.modules.settings.impl.BooleanSetting;
import im.expensive.settings.impl.NumberSetting;
import im.expensive.utils.math.MathUtil;
import im.expensive.utils.player.PlayerUtils;
import im.expensive.utils.render.color.ColorUtils;
import net.minecraft.client.entity.player.AbstractClientPlayerEntity;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector3d;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
@ModuleRegister(name = "TargetStrafe", category = Category.Combat, description = "тургитструф")
public class TargetStrafe extends Module {
private final NumberSetting range = new NumberSetting("Дистанция", 3.0F, 1.0F, 6.0F, 0.1F);
private final NumberSetting speed = new NumberSetting("Скорость", 0.3F, 0.1F, 1.5F, 0.05F);
private final BooleanSetting onlyFriends = new BooleanSetting("Только Друзья", false);
private final BooleanSetting autoSwitch = new BooleanSetting("Авто-Смена Направления", true);
private final BooleanSetting throughWalls = new BooleanSetting("Сквозь Стены", false);
private int direction = 1;
private PlayerEntity target = null;
private float silentYaw;
private float lastYaw;
private boolean rotating = false;
public TargetStrafe() {
addSettings(range, speed, onlyFriends, autoSwitch, throughWalls);
}
[USER=1367676]@override[/USER]
public void onEnable() {
super.onEnable();
target = null;
direction = 1;
}
[USER=1474073]@Subscribe[/USER]
public void onMove(EventMove event) {
if (mc.player == null || mc.world == null) return;
target = findTarget();
if (target == null) return;
double distanceToTarget = mc.player.getDistanceSq(target);
double targetRange = range.getFloatValue() * range.getFloatValue();
if (distanceToTarget > targetRange) {
Vector3d moveVec = calculateMoveVectorToTarget(target);
event.setX(moveVec.x * speed.getFloatValue());
event.setZ(moveVec.z * speed.getFloatValue());
return;
}
Vector3d strafeVec = calculateStrafeVector(target);
event.setX(strafeVec.x * speed.getFloatValue());
event.setZ(strafeVec.z * speed.getFloatValue());
if (autoSwitch.getBoolValue() && wouldCollideWithBlocks(strafeVec)) {
switchDirection();
}
}
[USER=1474073]@Subscribe[/USER]
public void onMotion(EventMotion event) {
if (mc.player == null || target == null) return;
if (event.getType() == EventMotion.Type.PRE) {
lastYaw = mc.player.rotationYaw;
if (rotating) {
event.setYaw(silentYaw);
}
}
else if (event.getType() == EventMotion.Type.POST) {
mc.player.rotationYaw = lastYaw;
mc.player.prevRotationYaw = lastYaw;
}
}
private PlayerEntity findTarget() {
if (mc.world == null) return null;
List<PlayerEntity> possibleTargets = mc.world.getPlayers().stream()
.filter(player -> player != mc.player)
.filter(player -> PlayerUtils.isNameValid(player.getName().getString()))
.filter(player -> !onlyFriends.getBoolValue() || FriendStorage.isFriend(player.getGameProfile().getName()))
.filter(player -> mc.player.canEntityBeSeen(player) || throughWalls.getBoolValue())
.sorted(Comparator.comparingDouble(player -> mc.player.getDistanceSq(player)))
.collect(Collectors.toList());
return possibleTargets.isEmpty() ? null : possibleTargets.get(0);
}
private Vector3d calculateMoveVectorToTarget(Entity target) {
double x = target.getPosX() - mc.player.getPosX();
double z = target.getPosZ() - mc.player.getPosZ();
double distance = Math.sqrt(x * x + z * z);
if (distance > 0) {
x /= distance;
z /= distance;
}
return new Vector3d(x, 0, z);
}
private Vector3d calculateStrafeVector(Entity target) {
double x = target.getPosX() - mc.player.getPosX();
double z = target.getPosZ() - mc.player.getPosZ();
double distance = Math.sqrt(x * x + z * z);
if (distance > 0) {
x /= distance;
z /= distance;
}
double tangentX = -z * direction;
double tangentZ = x * direction;
double angle = Math.toDegrees(Math.atan2(tangentZ, tangentX)) - 90;
silentYaw = (float) angle;
rotating = true;
return new Vector3d(tangentX, 0, tangentZ);
}
private boolean wouldCollideWithBlocks(Vector3d moveVec) {
if (!autoSwitch.getBoolValue()) return false;
double nextX = mc.player.getPosX() + moveVec.x * speed.getFloatValue();
double nextZ = mc.player.getPosZ() + moveVec.z * speed.getFloatValue();
return !mc.world.getBlockState(MathUtil.getBlockPos(nextX, mc.player.getPosY(), nextZ)).isAir() ||
!mc.world.getBlockState(MathUtil.getBlockPos(nextX, mc.player.getPosY() + 1, nextZ)).isAir();
}
private void switchDirection() {
direction *= -1;
}
public int getDirection() {
return direction;
}
public void setDirection(int direction) {
this.direction = direction == 0 ? 1 : direction > 0 ? 1 : -1;
}
public PlayerEntity getTarget() {
return target;
}
}