- Выберите загрузчик игры
- Fabric
applefarm под рокстар, вроде из ростислав клиента
applefarm:
package moscow.rockstar.systems.modules.modules.other;
import moscow.rockstar.systems.modules.api.ModuleCategory;
import moscow.rockstar.systems.modules.api.ModuleInfo;
import moscow.rockstar.systems.modules.impl.BaseModule;
import moscow.rockstar.utility.time.Timer;
import net.minecraft.block.AirBlock;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.SaplingBlock;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.util.ActionResult;
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;
@ModuleInfo(
name = "AppleFarm",
category = ModuleCategory.OTHER,
desc = "Фармит яблоки"
)
public class AppleFarm extends BaseModule {
private static final int RADIUS = 6;
private enum State {
BREAK_TREE,
WAIT_DROP,
PLACE_SAPLING,
BONEMEAL,
}
private State state = State.BREAK_TREE;
private final Timer actionTimer = new Timer();
private final Timer waitTimer = new Timer();
public AppleFarm() {}
@Override
public void onEnable() {
state = State.BREAK_TREE;
actionTimer.reset();
super.onEnable();
}
@Override
public void onDisable() {
state = State.BREAK_TREE;
super.onDisable();
}
@Override
public void tick() {
super.tick();
ClientPlayerEntity player = mc.player;
if (player == null || mc.world == null || mc.interactionManager == null) return;
switch (state) {
// 1. Рубим дерево
case BREAK_TREE -> {
if (!actionTimer.finished(80)) return;
selectBestAxe(player);
BlockPos log = findNearestBlock(player.getBlockPos(), RADIUS,
Blocks.OAK_LOG, Blocks.OAK_LEAVES,
Blocks.BIRCH_LOG, Blocks.BIRCH_LEAVES);
if (log == null) {
// Всё срубили
waitTimer.reset();
state = State.WAIT_DROP;
return;
}
lookAt(player, log);
mc.interactionManager.attackBlock(log, Direction.UP);
mc.interactionManager.updateBlockBreakingProgress(log, Direction.UP);
actionTimer.reset();
}
// 2. Ждём дроп
case WAIT_DROP -> {
if (!waitTimer.finished(1500)) return;
if (hasSapling(player)) {
state = State.PLACE_SAPLING;
} else {
state = State.BREAK_TREE; // нет саженца — ищем новое дерево
}
actionTimer.reset();
}
// 3. Ставим саженец — просто ищем любой блок рядом куда можно поставить
case PLACE_SAPLING -> {
if (!actionTimer.finished(150)) return;
// Ищем любое место где можно поставить саженец
BlockPos ground = findPlantableSpot(player.getBlockPos());
if (ground == null) {
// Нет места — попробуем ещё раз через тик
return;
}
// Саженец уже стоит где-то — идём поливать
BlockPos existingSapling = findNearestBlock(player.getBlockPos(), RADIUS,
Blocks.OAK_SAPLING, Blocks.BIRCH_SAPLING);
if (existingSapling != null) {
state = State.BONEMEAL;
actionTimer.reset();
return;
}
selectItem(player, Items.OAK_SAPLING);
lookAt(player, ground);
if (!isLookingAt(player, ground, 8f)) return;
BlockHitResult hit = new BlockHitResult(
Vec3d.ofCenter(ground).add(0, 0.5, 0),
Direction.UP,
ground,
false
);
ActionResult result = mc.interactionManager.interactBlock(player, Hand.MAIN_HAND, hit);
if (result.isAccepted()) {
state = State.BONEMEAL;
}
actionTimer.reset();
}
// 4. Поливаем костной мукой
case BONEMEAL -> {
if (!actionTimer.finished(80)) return;
// Дерево выросло — рубим
BlockPos log = findNearestBlock(player.getBlockPos(), RADIUS,
Blocks.OAK_LOG, Blocks.BIRCH_LOG);
if (log != null) {
state = State.BREAK_TREE;
actionTimer.reset();
return;
}
// Ищем саженец
BlockPos sapling = findNearestBlock(player.getBlockPos(), RADIUS,
Blocks.OAK_SAPLING, Blocks.BIRCH_SAPLING);
// Саженец пропал — сажаем снова
if (sapling == null) {
state = State.PLACE_SAPLING;
actionTimer.reset();
return;
}
// Нет костной муки — ждём пока вырастет само
if (!hasBoneMeal(player)) return;
selectItem(player, Items.BONE_MEAL);
lookAt(player, sapling);
if (!isLookingAt(player, sapling, 8f)) return;
BlockHitResult hit = new BlockHitResult(
Vec3d.ofCenter(sapling),
Direction.UP,
sapling,
false
);
mc.interactionManager.interactBlock(player, Hand.MAIN_HAND, hit);
actionTimer.reset();
}
}
}
// ---------------------------------------------------------------
/** Ищет любой блок рядом куда можно поставить саженец:
* земля/трава/торф снизу + воздух сверху */
private BlockPos findPlantableSpot(BlockPos center) {
for (int r = 0; r <= RADIUS; r++) {
for (int x = -r; x <= r; x++) {
for (int z = -r; z <= r; z++) {
for (int y = -2; y <= 2; y++) {
BlockPos pos = center.add(x, y, z);
if (canPlantSapling(pos)) return pos;
}
}
}
}
return null;
}
/** Проверяет можно ли поставить саженец на этот блок */
private boolean canPlantSapling(BlockPos pos) {
net.minecraft.block.Block below = mc.world.getBlockState(pos).getBlock();
net.minecraft.block.Block above = mc.world.getBlockState(pos.up()).getBlock();
boolean goodSoil = below == Blocks.GRASS_BLOCK
|| below == Blocks.DIRT
|| below == Blocks.COARSE_DIRT
|| below == Blocks.PODZOL
|| below == Blocks.ROOTED_DIRT
|| below == Blocks.MOSS_BLOCK;
boolean airAbove = above instanceof AirBlock;
return goodSoil && airAbove;
}
private BlockPos findNearestBlock(BlockPos center, int radius, net.minecraft.block.Block... blocks) {
BlockPos nearest = null;
double nearestDist = Double.MAX_VALUE;
for (int x = -radius; x <= radius; x++) {
for (int y = -radius; y <= radius; y++) {
for (int z = -radius; z <= radius; z++) {
BlockPos pos = center.add(x, y, z);
net.minecraft.block.Block b = mc.world.getBlockState(pos).getBlock();
for (net.minecraft.block.Block t : blocks) {
if (b == t) {
double d = center.getSquaredDistance(pos);
if (d < nearestDist) { nearestDist = d; nearest = pos; }
}
}
}
}
}
return nearest;
}
private void lookAt(ClientPlayerEntity player, BlockPos pos) {
Vec3d eyes = player.getEyePos();
Vec3d target = Vec3d.ofCenter(pos);
double dx = target.x - eyes.x;
double dy = target.y - eyes.y;
double dz = target.z - eyes.z;
double dist = Math.sqrt(dx * dx + dz * dz);
player.setYaw((float) Math.toDegrees(Math.atan2(dz, dx)) - 90f);
player.setPitch((float) -Math.toDegrees(Math.atan2(dy, dist)));
}
private boolean isLookingAt(ClientPlayerEntity player, BlockPos pos, float maxDeg) {
Vec3d eyes = player.getEyePos();
Vec3d target = Vec3d.ofCenter(pos);
double dx = target.x - eyes.x;
double dy = target.y - eyes.y;
double dz = target.z - eyes.z;
double dist = Math.sqrt(dx * dx + dz * dz);
float wantYaw = (float) Math.toDegrees(Math.atan2(dz, dx)) - 90f;
float wantPitch = (float) -Math.toDegrees(Math.atan2(dy, dist));
return Math.abs(wrap(player.getYaw() - wantYaw)) < maxDeg
&& Math.abs(wrap(player.getPitch() - wantPitch)) < maxDeg;
}
private float wrap(float d) {
d = d % 360f;
if (d < -180f) d += 360f;
if (d > 180f) d -= 360f;
return d;
}
private boolean hasSapling(ClientPlayerEntity p) {
for (int i = 0; i < p.getInventory().size(); i++)
if (p.getInventory().getStack(i).getItem() == Items.OAK_SAPLING) return true;
return false;
}
private boolean hasBoneMeal(ClientPlayerEntity p) {
for (int i = 0; i < p.getInventory().size(); i++)
if (p.getInventory().getStack(i).getItem() == Items.BONE_MEAL) return true;
return false;
}
private void selectBestAxe(ClientPlayerEntity player) {
net.minecraft.item.Item[] axes = {
Items.NETHERITE_AXE, Items.DIAMOND_AXE,
Items.IRON_AXE, Items.GOLDEN_AXE,
Items.STONE_AXE, Items.WOODEN_AXE
};
for (net.minecraft.item.Item axe : axes)
for (int i = 0; i < 9; i++)
if (player.getInventory().getStack(i).getItem() == axe) {
player.getInventory().selectedSlot = i; return;
}
}
private void selectItem(ClientPlayerEntity player, net.minecraft.item.Item item) {
for (int i = 0; i < 9; i++)
if (player.getInventory().getStack(i).getItem() == item) {
player.getInventory().selectedSlot = i; return;
}
}
}