Начинающий
- Статус
- Оффлайн
- Регистрация
- 6 Сен 2025
- Сообщения
- 27
- Реакции
- 0
- Выберите загрузчик игры
- Fabric
Средний модуль ищет базы на фантайме, есть немного ии кода, логика +- хорошая есть защита от лавы/воды пропасти атаки и другие фишки, не захотел ебаться с баритоном просто написал такой модуль. Кто хочет - пастите.
Может кому пригодиться :3
Может кому пригодиться :3
код:
package fun.vortex.features.impl.player;
import fun.vortex.events.player.TickEvent;
import fun.vortex.features.module.ModuleCategory;
import fun.vortex.features.module.setting.implement.SelectSetting;
import fun.vortex.features.module.setting.implement.SliderSettings;
import fun.vortex.utils.client.chat.ChatMessage;
import fun.vortex.utils.client.managers.event.EventHandler;
import fun.vortex.utils.features.aura.warp.TurnsConnection;
import net.minecraft.block.BlockState;
import fun.vortex.events.render.WorldRenderEvent;
import fun.vortex.utils.display.color.ColorAssist;
import net.minecraft.util.math.Box;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.ItemEnchantmentsComponent;
import net.minecraft.component.type.ToolComponent;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.item.PickaxeItem;
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import fun.vortex.features.module.Module;
public class FTBaseFinder extends Module {
private final SelectSetting direction = new SelectSetting("Направление", "Куда копать")
.value("North", "East", "South", "West").selected("North");
private final SliderSettings targetY = new SliderSettings("Высота", "Целевая высота")
.range(-60, 60).setValue(15);
private final SelectSetting oreType = new SelectSetting("Блок проверки", "Что ставить")
.value("Diamond Ore", "Emerald Ore").selected("Diamond Ore");
private final SliderSettings checkDistance = new SliderSettings("Дистанция проверки", "Раз в сколько блоков ставить руду")
.range(5, 100).setValue(25);
private boolean diggingDown = true;
private int distanceCounter = 0;
private BlockPos blockToBreak = null;
public FTBaseFinder() {
super("FT-BaseFinder", "FTBaseFinder", ModuleCategory.PLAYER);
setup(direction, targetY, oreType, checkDistance);
}
@Override
public void activate() {
if (mc.player == null) {
this.switchState();
return;
}
if (!hasRequiredItems()) {
ChatMessage.brandmessage("§c[Ошибка] §fНет кирки на Шелковое касание или руды в хотбаре!");
this.switchState();
return;
}
diggingDown = true;
distanceCounter = 0;
blockToBreak = null;
ChatMessage.brandmessage("§a[Старт] §fСпускаюсь на высоту " + targetY.getInt());
super.activate();
}
@Override
public void deactivate() {
if (mc.options != null) {
mc.options.forwardKey.setPressed(false);
}
super.deactivate();
}
private BlockPos pendingOrePos = null;
private BlockPos shouldPlaceOreAfterBreak = null;
private boolean isBypassing = false;
private int bypassTicks = 0;
private BlockPos bypassTarget = null;
@EventHandler
public void onTick(TickEvent ignored) {
if (mc.player == null || mc.world == null) return;
if (mc.player.hurtTime > 0) {
boolean isEntityDamage = mc.world.getEntitiesByClass(net.minecraft.entity.mob.HostileEntity.class,
mc.player.getBoundingBox().expand(5), e -> true).size() > 0;
if (isEntityDamage && System.currentTimeMillis() - lastDamageTime > 5000) {
ChatMessage.brandmessage("§c§l[ВНИМАНИЕ] §fВас атакует моб! Остановка.");
this.switchState();
return;
}
}
if (pendingOrePos != null && mc.world.isAir(pendingOrePos)) {
if (!tryPlaceOre(pendingOrePos)) {
ChatMessage.brandmessage("§6§l[БАЗА!] §fПриват на: §a" + pendingOrePos.toShortString());
this.switchState();
return;
} else {
mineBackOre(pendingOrePos);
pendingOrePos = null;
}
}
if (blockToBreak != null) {
if (mc.world.isAir(blockToBreak)) {
blockToBreak = null;
} else {
processBlockMining(blockToBreak);
return;
}
}
if (diggingDown) {
handleDescending();
} else {
handleTunneling();
}
}
private BlockPos lastCheckPos = null;
private long lastDamageTime = 0;
private void handleDescending() {
BlockPos playerPos = BlockPos.ofFloored(mc.player.getPos());
BlockPos underPlayer = playerPos.down();
if (isLiquidBelow(underPlayer)) {
ChatMessage.brandmessage("§c[!] §fПод ногами обнаружена жидкость. Запуск сканирования 10x10...");
BlockPos safePoint = findBestSafePoint(playerPos);
if (safePoint != null) {
double distance = Math.sqrt(playerPos.getSquaredDistance(safePoint));
ChatMessage.brandmessage(String.format("§a[Навигатор] §fНайдена безопасная зона в %.1f м. Обхожу...", distance));
moveTowards(safePoint);
} else {
ChatMessage.brandmessage("§4[Крит] §fВ радиусе 10 блоков нет безопасных мест. Смена вектора...");
direction.selected(Direction.Type.HORIZONTAL.random(mc.world.random).asString());
}
return;
}
if (mc.player.getY() <= targetY.getValue()) {
diggingDown = false;
ChatMessage.brandmessage("§6[Инфо] §fЦелевая высота " + targetY.getInt() + " достигнута. Начинаю копку туннеля.");
return;
}
if (!mc.world.isAir(underPlayer)) {
blockToBreak = underPlayer;
}
}
private BlockPos findBestSafePoint(BlockPos startPos) {
BlockPos bestPos = null;
double minDistance = Double.MAX_VALUE;
for (int x = -10; x <= 10; x++) {
for (int z = -10; z <= 10; z++) {
BlockPos checkPos = startPos.add(x, 0, z);
if (isValidSafeSpot(checkPos)) {
double dist = startPos.getSquaredDistance(checkPos);
if (dist < minDistance) {
minDistance = dist;
bestPos = checkPos;
}
}
}
}
return bestPos;
}
private boolean isValidSafeSpot(BlockPos pos) {
boolean isSpaceClear = mc.world.getBlockState(pos).isAir() &&
mc.world.getBlockState(pos.up()).isAir();
if (!isSpaceClear) return false;
for (int i = 0; i <= 5; i++) {
if (mc.world.getBlockState(pos.down(i)).isLiquid()) {
return false;
}
}
return !mc.world.getBlockState(pos.down()).isAir();
}
private boolean isLiquidBelow(BlockPos startPos) {
for (int i = 0; i < 5; i++) {
BlockState state = mc.world.getBlockState(startPos.down(i));
if (state.isLiquid()) return true;
}
return false;
}
private void tryToBypassDanger(BlockPos currentPos) {
for (Direction dir : Direction.Type.HORIZONTAL) {
BlockPos sidePos = currentPos.offset(dir);
if (!isLiquidBelow(sidePos) && mc.world.isAir(sidePos)) {
moveTowards(sidePos);
return;
}
}
ChatMessage.brandmessage("§c[Внимание] §f Безопасный путь не найден. Стоп.");
this.switchState();
}
private void moveTowards(BlockPos pos) {
if (mc.player == null) return;
rotateHeadToBlock(pos);
double dx = pos.getX() + 0.5 - mc.player.getX();
double dz = pos.getZ() + 0.5 - mc.player.getZ();
double distance = Math.sqrt(dx * dx + dz * dz);
if (distance > 0.3) {
mc.options.forwardKey.setPressed(true);
if (mc.player.horizontalCollision) {
mc.options.jumpKey.setPressed(true);
} else {
mc.options.jumpKey.setPressed(false);
}
} else {
mc.options.forwardKey.setPressed(false);
mc.options.jumpKey.setPressed(false);
}
}
private void handleTunneling() {
Direction dir = Direction.byName(direction.getSelected().toLowerCase());
if (dir == null) dir = Direction.NORTH;
BlockPos playerPos = BlockPos.ofFloored(mc.player.getPos());
BlockPos forwardLower = playerPos.offset(dir);
BlockPos forwardUpper = forwardLower.up();
BlockPos gapPos = forwardLower.down();
// Проверка жидкостей
if (mc.world.getBlockState(forwardLower).isLiquid() || mc.world.getBlockState(forwardUpper).isLiquid()) {
direction.selected(dir.rotateYClockwise().asString());
return;
}
if (mc.world.getBlockState(gapPos).isAir() || mc.world.getBlockState(gapPos).isLiquid()) {
mc.options.forwardKey.setPressed(false);
placeBridge(gapPos);
return;
}
if (!isBlockPassable(forwardUpper) || !isBlockPassable(forwardLower)) {
mc.options.forwardKey.setPressed(false);
blockToBreak = !isBlockPassable(forwardUpper) ? forwardUpper : forwardLower;
} else {
mc.options.sneakKey.setPressed(false);
if (blockToBreak == null && pendingOrePos == null) {
moveForward();
// ИНИЦИАЛИЗАЦИЯ ПОЗИЦИИ
if (lastCheckPos == null) lastCheckPos = playerPos;
double dist = Math.sqrt(playerPos.getSquaredDistance(lastCheckPos));
if (dist >= checkDistance.getValue()) {
mc.options.forwardKey.setPressed(false);
checkBaseWithOre(dir);
lastCheckPos = playerPos; // Обнуляем точку отсчета
}
}
}
}
private boolean checkForDanger(BlockPos pos) {
if (mc.world == null) return false;
BlockState floor = mc.world.getBlockState(pos.down());
boolean isVoid = floor.isAir();
boolean isLiquid = mc.world.getBlockState(pos).isLiquid() || floor.isLiquid();
return isVoid || isLiquid;
}
private void processBlockMining(BlockPos pos) {
if (mc.world == null || mc.player == null || mc.interactionManager == null) return;
if (checkForLiquids(pos)) {
ChatMessage.brandmessage("§c[Внимание] §fОбнаружена лава/вода. Остановка.");
this.switchState();
return;
}
selectBestTool(mc.world.getBlockState(pos));
rotateHeadToBlock(pos);
mc.interactionManager.updateBlockBreakingProgress(pos, Direction.UP);
mc.player.swingHand(Hand.MAIN_HAND);
}
private int findFillerBlock() {
for (int i = 0; i < 9; i++) {
ItemStack stack = mc.player.getInventory().getStack(i);
if (stack.isEmpty()) continue;
String name = stack.getItem().toString();
if (name.contains("stone") || name.contains("dirt") || name.contains("cobble") ||
name.contains("netherrack") || name.contains("deepslate") || name.contains("andesite")) {
return i;
}
}
return -1;
}
private void placeBridge(BlockPos targetPos) {
int fillerSlot = findFillerBlock();
if (fillerSlot == -1) {
ChatMessage.brandmessage("§c[Ошибка] §fНет блоков для застройки!");
this.switchState();
return;
}
mc.options.forwardKey.setPressed(false);
mc.options.sneakKey.setPressed(true);
int oldSlot = mc.player.getInventory().selectedSlot;
mc.player.getInventory().selectedSlot = fillerSlot;
rotateHeadToBlock(targetPos);
BlockHitResult hit = new BlockHitResult(targetPos.toCenterPos(), Direction.UP, targetPos, false);
mc.interactionManager.interactBlock(mc.player, Hand.MAIN_HAND, hit);
mc.player.swingHand(Hand.MAIN_HAND);
mc.player.getInventory().selectedSlot = oldSlot;
}
@EventHandler
public void onRender3D(WorldRenderEvent event) {
if (!state || mc.world == null || mc.player == null) return;
if (blockToBreak != null) {
fun.vortex.utils.display.geometry.Render3D.drawBox(new Box(blockToBreak), ColorAssist.getColor(255, 0, 0, 100), 1);
}
if (!diggingDown) {
Direction dir = Direction.byName(direction.getSelected().toLowerCase());
if (dir != null) {
BlockPos p = mc.player.getBlockPos();
BlockPos f1 = p.offset(dir);
BlockPos f2 = p.up().offset(dir);
if (!mc.world.isAir(f1) && !f1.equals(blockToBreak)) fun.vortex.utils.display.geometry.Render3D.drawBox(new Box(f1), ColorAssist.getColor(0, 255, 0, 50), 1);
if (!mc.world.isAir(f2) && !f2.equals(blockToBreak)) fun.vortex.utils.display.geometry.Render3D.drawBox(new Box(f2), ColorAssist.getColor(0, 255, 0, 50), 1);
}
}
}
private void checkBaseWithOre(Direction dir) {
Direction sideDir = dir.rotateYClockwise();
BlockPos wallPos = mc.player.getBlockPos().offset(sideDir).up();
if (!mc.world.isAir(wallPos)) {
blockToBreak = wallPos;
pendingOrePos = wallPos;
shouldPlaceOreAfterBreak = wallPos;
}
}
private void selectBestTool(BlockState blockState) {
if (mc.player == null) return;
int bestSlot = -1;
float bestSpeed = 0;
for (int i = 0; i < 9; i++) {
ItemStack stack = mc.player.getInventory().getStack(i);
if (stack.isEmpty()) continue;
ToolComponent tool = stack.get(DataComponentTypes.TOOL);
float speed = (tool != null) ? tool.getSpeed(blockState) : 1.0f;
if (speed > bestSpeed) {
bestSpeed = speed;
bestSlot = i;
}
}
if (bestSlot != -1) {
mc.player.getInventory().selectedSlot = bestSlot;
}
}
private void rotateHeadToBlock(BlockPos pos) {
if (mc.player == null) return;
Vec3d target = pos.toCenterPos();
Vec3d eyePos = mc.player.getEyePos();
double dx = target.x - eyePos.x;
double dy = target.y - eyePos.y;
double dz = target.z - eyePos.z;
float yaw = (float) Math.toDegrees(Math.atan2(dz, dx)) - 90.0F;
float pitch = (float) -Math.toDegrees(Math.atan2(dy, Math.sqrt(dx * dx + dz * dz)));
double gcd = fun.vortex.utils.math.calc.Calculate.computeGcd();
if (gcd > 0) {
float lastYaw = TurnsConnection.INSTANCE.getRotation().getYaw();
float lastPitch = TurnsConnection.INSTANCE.getRotation().getPitch();
float deltaYaw = yaw - lastYaw;
float deltaPitch = pitch - lastPitch;
yaw = lastYaw + (float) (deltaYaw - (deltaYaw % gcd));
pitch = lastPitch + (float) (deltaPitch - (deltaPitch % gcd));
}
pitch = net.minecraft.util.math.MathHelper.clamp(pitch, -90.0f, 90.0f);
TurnsConnection.INSTANCE.getRotation().setYaw(yaw);
TurnsConnection.INSTANCE.getRotation().setPitch(pitch);
mc.player.setYaw(yaw);
mc.player.setPitch(pitch);
}
private void moveForward() {
if (mc.options == null) return;
mc.options.forwardKey.setPressed(true);
}
private boolean isBlockPassable(BlockPos pos) {
if (mc.world == null) return false;
return !mc.world.getBlockState(pos).isOpaque();
}
private boolean checkForLiquids(BlockPos pos) {
if (mc.world == null) return false;
return mc.world.getBlockState(pos).isLiquid();
}
private boolean tryPlaceOre(BlockPos pos) {
if (mc.player == null || mc.interactionManager == null || mc.world == null) return false;
int oreSlot = findOreSlot();
if (oreSlot == -1) return false;
int oldSlot = mc.player.getInventory().selectedSlot;
mc.player.getInventory().selectedSlot = oreSlot;
rotateHeadToBlock(pos);
BlockHitResult hitResult = new BlockHitResult(pos.toCenterPos(), Direction.UP, pos, false);
mc.interactionManager.interactBlock(mc.player, Hand.MAIN_HAND, hitResult);
mc.player.swingHand(Hand.MAIN_HAND);
boolean placed = !mc.world.getBlockState(pos).isAir();
mc.player.getInventory().selectedSlot = oldSlot;
return placed;
}
private void mineBackOre(BlockPos pos) {
if (mc.player == null || mc.player.networkHandler == null) return;
int pickaxeSlot = findSilkTouchPickaxe();
if (pickaxeSlot == -1) return;
int oldSlot = mc.player.getInventory().selectedSlot;
mc.player.getInventory().selectedSlot = pickaxeSlot;
mc.player.networkHandler.sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.START_DESTROY_BLOCK, pos, Direction.UP));
mc.player.networkHandler.sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.STOP_DESTROY_BLOCK, pos, Direction.UP));
mc.player.swingHand(Hand.MAIN_HAND);
mc.player.getInventory().selectedSlot = oldSlot;
}
private boolean hasRequiredItems() {
if (mc.player == null) return false;
return findSilkTouchPickaxe() != -1 && findOreSlot() != -1;
}
private int findSilkTouchPickaxe() {
if (mc.player == null) return -1;
for (int i = 0; i < 9; i++) {
ItemStack stack = mc.player.getInventory().getStack(i);
if (stack.getItem() instanceof PickaxeItem) {
ItemEnchantmentsComponent enchants = stack.get(DataComponentTypes.ENCHANTMENTS);
if (enchants != null) {
for (RegistryEntry<Enchantment> enchant : enchants.getEnchantments()) {
if (enchant.matchesKey(Enchantments.SILK_TOUCH)) return i;
}
}
}
}
return -1;
}
private int findOreSlot() {
if (mc.player == null) return -1;
for (int i = 0; i < 9; i++) {
ItemStack s = mc.player.getInventory().getStack(i);
if (oreType.isSelected("Diamond Ore") && s.isOf(Items.DIAMOND_ORE)) return i;
if (oreType.isSelected("Emerald Ore") && s.isOf(Items.EMERALD_ORE)) return i;
}
return -1;
}
}