Начинающий
- Статус
- Оффлайн
- Регистрация
- 21 Ноя 2024
- Сообщения
- 20
- Реакции
- 1
- Выберите загрузчик игры
- Forge
- Fabric
- OptiFine
- ForgeOptiFine
Привет Югейм
Сливаю эксклюзивчик
Моя первая тема прошу без /del
Функция которая сама находит Ключ Карты На ReallyWorld (для работы нужен баритон)
Сразу пишу требуется Доработка (что-то может не работать)
Работает как баритон ищет вагонетки с сундуком если нету то либо копается либо ходит по миру ищет
Сливаю эксклюзивчик
Моя первая тема прошу без /del
Функция которая сама находит Ключ Карты На ReallyWorld (для работы нужен баритон)
Код:
package wtf.expensive.modules.impl.player;
import baritone.api.BaritoneAPI;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalNear;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.entity.item.minecart.ChestMinecartEntity;
import net.minecraft.inventory.container.ClickType;
import net.minecraft.inventory.container.Container;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.util.Hand;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.block.BlockState;
import net.minecraft.network.play.client.CPlayerDiggingPacket;
import wtf.expensive.events.Event;
import wtf.expensive.events.impl.player.EventMotion;
import wtf.expensive.events.impl.player.EventUpdate;
import wtf.expensive.events.impl.render.EventRender;
import wtf.expensive.modules.Function;
import wtf.expensive.modules.FunctionAnnotation;
import wtf.expensive.modules.Type;
import wtf.expensive.modules.settings.imp.BooleanOption;
import wtf.expensive.modules.settings.imp.SliderSetting;
import wtf.expensive.util.font.Fonts;
import wtf.expensive.util.misc.TimerUtil;
import java.util.Comparator;
import java.util.List;
@FunctionAnnotation(name = "AutoCard", type = Type.Player)
public class AutoCard extends Function {
private final SliderSetting scanRadius = new SliderSetting("Radius", 64f, 8f, 256f, 1f);
private final SliderSetting nearRadius = new SliderSetting("Goal Near", 2f, 1f, 5f, 1f);
private final BooleanOption autoBreak = new BooleanOption("Break after loot", true);
private final BooleanOption useBaritone = new BooleanOption("Use Baritone", true);
private final BooleanOption exploreIfNoCart = new BooleanOption("Route search when no cart", true);
private final SliderSetting searchStep = new SliderSetting("Route step", 64f, 16f, 256f, 8f);
private final BooleanOption optimize3x3 = new BooleanOption("Assume 3x3 pick", false);
private final BooleanOption optimizeEfficiency10 = new BooleanOption("Assume Efficiency X", false);
private enum Mode { IDLE, PATH_TO_CART, INTERACT_CART, BREAK_CART, LOOT_GROUND, SEARCH_ROUTE }
private Mode mode = Mode.IDLE;
private ChestMinecartEntity targetCart;
private boolean interactionStarted;
private int lootedThisCart;
private long startMs;
private final TimerUtil pfTimer = new TimerUtil();
private final TimerUtil interactTimer = new TimerUtil();
private final TimerUtil modeSwitchCooldown = new TimerUtil();
private final TimerUtil fixAllTimer = new TimerUtil();
private final TimerUtil healTimer = new TimerUtil();
private final TimerUtil lootTimer = new TimerUtil();
private int cartLostTicks;
private final int cartLostThreshold = 20; // ~1 сек
private BlockPos lastCartGoal;
public AutoCard() {
addSettings(scanRadius, nearRadius, autoBreak, useBaritone, exploreIfNoCart, searchStep, optimize3x3, optimizeEfficiency10);
}
@Override
protected void onEnable() {
mode = Mode.IDLE;
targetCart = null;
interactionStarted = false;
lootedThisCart = 0;
startMs = System.currentTimeMillis();
cartLostTicks = 0;
lastCartGoal = null;
applyBaritoneOptimizations();
stopBaritone();
}
@Override
protected void onDisable() {
pressForward(false);
stopBaritone();
resetBaritoneOptimizations();
}
@Override
public void onEvent(Event event) {
if (mc.player == null || mc.world == null) return;
if (event instanceof EventUpdate) {
// try to resolve phantom blocks that might block movement
fixPhantomsAround();
// periodic maintenance commands
if (fixAllTimer.hasTimeElapsed(120000)) { // 2 minutes
mc.player.sendChatMessage("/fix");
fixAllTimer.reset();
}
if (healTimer.hasTimeElapsed(90000)) { // 1.5 minutes
mc.player.sendChatMessage("/heal");
healTimer.reset();
}
if (pfTimer.hasTimeElapsed(150)) {
pfTimer.reset();
applyBaritoneOptimizations();
updateTargetCart();
decideMode();
if (mode == Mode.PATH_TO_CART) pathWithBaritone();
}
switch (mode) {
case PATH_TO_CART -> followWithBaritone();
case INTERACT_CART -> handleCartInteraction();
case BREAK_CART -> attackCart();
case LOOT_GROUND -> lootGround();
case SEARCH_ROUTE -> ensureSearchRoute();
default -> {
}
}
}
if (event instanceof EventMotion) {
if (mode == Mode.BREAK_CART && targetCart != null) {
Vector3d look = targetCart.getPositionVec().add(0, 0.5, 0);
lookAtSmooth(look, 10f);
}
}
if (event instanceof EventRender e && e.isRender2D()) {
renderInfo(e.matrixStack);
}
}
private void decideMode() {
if (!modeSwitchCooldown.hasTimeElapsed(200)) {
return;
}
if (targetCart != null && targetCart.isAlive() && cartLostTicks < cartLostThreshold) {
mode = Mode.PATH_TO_CART;
return;
}
mode = exploreIfNoCart.get() && useBaritone.get() ? Mode.SEARCH_ROUTE : Mode.IDLE;
}
private void updateTargetCart() {
if (targetCart != null && targetCart.isAlive()) {
if (targetCart.getDistance(mc.player) > scanRadius.getValue().floatValue() + 4f) {
cartLostTicks++;
} else {
cartLostTicks = 0;
}
if (cartLostTicks < cartLostThreshold) return; // держим цель, не даем флип-флоп
}
ChestMinecartEntity found = findNearestCart(scanRadius.getValue().intValue());
if (found != null) {
targetCart = found;
lootedThisCart = 0;
cartLostTicks = 0;
modeSwitchCooldown.reset();
}
}
private ChestMinecartEntity findNearestCart(int radius) {
AxisAlignedBB box = new AxisAlignedBB(mc.player.getPosition()).grow(radius);
List<ChestMinecartEntity> list = mc.world.getEntitiesWithinAABB(ChestMinecartEntity.class, box);
return list.stream()
.min(Comparator.comparingDouble(e -> e.getDistanceSq(mc.player)))
.orElse(null);
}
private void pathWithBaritone() {
if (!useBaritone.get() || targetCart == null) return;
BlockPos goal = targetCart.getPosition();
int r = Math.max(1, nearRadius.getValue().intValue());
if (lastCartGoal == null || !lastCartGoal.equals(goal)) {
Goal g = new GoalNear(goal, r);
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(g);
lastCartGoal = goal;
}
}
private BlockPos currentSearchGoal;
private final TimerUtil searchTimer = new TimerUtil();
private final long searchGoalTimeoutMs = 15000;
private void ensureSearchRoute() {
if (!useBaritone.get() || !exploreIfNoCart.get()) return;
if (currentSearchGoal == null || reached(currentSearchGoal) || searchTimer.hasTimeElapsed(searchGoalTimeoutMs)) {
currentSearchGoal = computeNextRouteGoal();
searchTimer.reset();
if (currentSearchGoal != null) {
Goal g = new GoalNear(currentSearchGoal, Math.max(1, nearRadius.getValue().intValue()));
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(g);
}
}
}
private boolean reached(BlockPos pos) {
return mc.player.getPositionVec().distanceTo(new Vector3d(pos.getX() + 0.5, mc.player.getPosY(), pos.getZ() + 0.5)) <= 3.0;
}
private BlockPos computeNextRouteGoal() {
float yaw = mc.player.rotationYaw;
double step = searchStep.getValue().doubleValue();
double rad = Math.toRadians(yaw);
double dx = -Math.sin(rad) * step;
double dz = Math.cos(rad) * step;
int x = (int) Math.round(mc.player.getPosX() + dx);
int z = (int) Math.round(mc.player.getPosZ() + dz);
int y = mc.player.getPosition().getY();
return new BlockPos(x, y, z);
}
private void followWithBaritone() {
if (targetCart == null || !targetCart.isAlive()) { stopBaritone(); mode = Mode.IDLE; return; }
if (mc.player.getDistance(targetCart) <= 3.0f) {
stopBaritone();
mode = Mode.INTERACT_CART;
interactionStarted = false;
modeSwitchCooldown.reset();
}
}
private void handleCartInteraction() {
if (targetCart == null || !targetCart.isAlive()) { mode = Mode.IDLE; interactionStarted = false; return; }
if (!interactionStarted) {
interactTimer.reset();
mc.playerController.interactWithEntity(mc.player, targetCart, Hand.MAIN_HAND);
interactionStarted = true;
}
if (mc.player.openContainer != null) {
boolean found = lootKeycardsFromOpen();
mc.player.closeScreen();
// If no card found, always break; if found, break only when setting enabled
mode = (!found || autoBreak.get()) ? Mode.BREAK_CART : Mode.IDLE;
interactionStarted = false;
return;
}
if (interactTimer.hasTimeElapsed(500)) {
interactTimer.reset();
mc.playerController.interactWithEntity(mc.player, targetCart, Hand.MAIN_HAND);
}
}
private boolean lootKeycardsFromOpen() {
if (mc.player.openContainer == null) return false;
boolean found = false;
Container c = mc.player.openContainer;
for (int slot = 0; slot < c.inventorySlots.size(); slot++) {
ItemStack stack = c.getSlot(slot).getStack();
if (isKeyCard(stack)) {
mc.playerController.windowClick(c.windowId, slot, 0, ClickType.QUICK_MOVE, mc.player);
lootedThisCart++;
found = true;
}
}
return found;
}
private void attackCart() {
if (targetCart == null || !targetCart.isAlive()) {
// switch to ground loot collection after the cart is destroyed
targetCart = null;
lootTimer.reset();
mode = Mode.LOOT_GROUND;
return;
}
mc.playerController.attackEntity(mc.player, targetCart);
mc.player.swingArm(Hand.MAIN_HAND);
}
private void lootGround() {
if (isInventoryFull()) {
dropJunkUntilSpace();
}
AxisAlignedBB box = new AxisAlignedBB(mc.player.getPosition()).grow(6);
List<net.minecraft.entity.item.ItemEntity> drops = mc.world.getEntitiesWithinAABB(net.minecraft.entity.item.ItemEntity.class, box);
net.minecraft.entity.item.ItemEntity nearest = drops.stream()
.min(Comparator.comparingDouble(e -> e.getDistanceSq(mc.player)))
.orElse(null);
if (nearest != null) {
double dist = mc.player.getDistance(nearest);
if (useBaritone.get()) {
BlockPos goal = nearest.getPosition();
Goal g = new GoalNear(goal, 1);
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(g);
} else {
pressForward(dist > 1.5);
}
}
if (lootTimer.hasTimeElapsed(3000) || nearest == null) {
pressForward(false);
stopBaritone();
mode = Mode.IDLE;
}
}
private boolean isInventoryFull() {
for (int i = 0; i < mc.player.inventory.mainInventory.size(); i++) {
ItemStack s = mc.player.inventory.mainInventory.get(i);
if (s.isEmpty()) return false;
}
return true;
}
private void dropJunkUntilSpace() {
for (int i = 0; i < mc.player.inventory.mainInventory.size(); i++) {
ItemStack s = mc.player.inventory.mainInventory.get(i);
if (!s.isEmpty() && isJunk(s)) {
try {
mc.playerController.windowClick(mc.player.container.windowId, i, 1, ClickType.THROW, mc.player);
return; // drop one stack then re-check next tick
} catch (Throwable ignored) {
}
}
}
}
private boolean isJunk(ItemStack stack) {
if (stack.isEmpty()) return false;
var item = stack.getItem();
return item == Items.TORCH
|| item == Items.MINECART
|| item == Items.POWERED_RAIL
|| item == Items.RAIL
|| item == Items.ANDESITE
|| item == Items.COBBLESTONE
|| item == Items.STONE
|| item == Items.PUMPKIN_SEEDS
|| item == Items.MELON_SEEDS
|| item == Items.CHEST
|| item == Items.IRON_INGOT
|| item == Items.DIAMOND
|| item == Items.GOLD_INGOT;
}
private boolean isKeyCard(ItemStack stack) {
if (stack.isEmpty()) return false;
StringBuilder textBuilder = new StringBuilder();
// Plain (stripped) display name
textBuilder.append(stack.getDisplayName().getString()).append(' ');
CompoundNBT tag = stack.getTag();
if (tag != null && tag.contains("display", 10)) {
CompoundNBT display = tag.getCompound("display");
// Raw JSON or legacy formatted name (may include colors)
if (display.contains("Name", 8)) {
String rawName = display.getString("Name");
textBuilder.append(rawName).append(' ');
}
// Lore lines are JSON strings in 1.16.5
if (display.contains("Lore", 9)) {
ListNBT loreList = display.getList("Lore", 8);
for (int i = 0; i < loreList.size(); i++) {
String loreEntry = loreList.getString(i);
textBuilder.append(loreEntry).append(' ');
}
}
}
String haystack = textBuilder.toString().toLowerCase();
boolean mentionsKeycard = haystack.contains("ключ") && haystack.contains("карт");
boolean mentionsColorWord = haystack.contains("син") || haystack.contains("зел") || haystack.contains("крас");
boolean mentionsJsonColor = haystack.contains("\"color\":\"blue\"")
|| haystack.contains("\"color\":\"green\"")
|| haystack.contains("\"color\":\"red\"");
boolean mentionsSectionColor = haystack.contains("§9") || haystack.contains("§a") || haystack.contains("§c");
// Extra lore keywords user requested
boolean mentionsUse = haystack.contains("использовать");
boolean mentionsTower = haystack.contains("башня");
return mentionsKeycard && (
mentionsColorWord || mentionsJsonColor || mentionsSectionColor ||
(mentionsUse && mentionsTower)
);
}
private void lookAtSmooth(Vector3d target, float speed) {
Vector3d eyes = mc.player.getEyePosition(1.0F);
Vector3d diff = target.subtract(eyes);
double dXZ = Math.sqrt(diff.x * diff.x + diff.z * diff.z);
float yaw = (float) (Math.toDegrees(Math.atan2(diff.z, diff.x)) - 90.0);
float pitch = (float) (-Math.toDegrees(Math.atan2(diff.y, dXZ)));
mc.player.rotationYaw = approach(mc.player.rotationYaw, yaw, speed);
mc.player.rotationPitch = approach(mc.player.rotationPitch, pitch, speed);
}
private float approach(float current, float target, float maxStep) {
float delta = wrapDegrees(target - current);
if (delta > maxStep) delta = maxStep;
if (delta < -maxStep) delta = -maxStep;
return current + delta;
}
private float wrapDegrees(float v) {
v %= 360f;
if (v >= 180f) v -= 360f;
if (v < -180f) v += 360f;
return v;
}
private void stopBaritone() {
try {
var baritone = BaritoneAPI.getProvider().getPrimaryBaritone();
var goalProc = baritone.getCustomGoalProcess();
goalProc.setGoal((Goal) null);
baritone.getPathingBehavior().cancelEverything();
} catch (Throwable ignored) {
}
}
private void pressForward(boolean pressed) {
mc.gameSettings.keyBindForward.setPressed(pressed);
}
private void renderInfo(MatrixStack stack) {
String title = "AutoCard";
String l1 = "Carts: " + lootedThisCart;
float w = Math.max(Fonts.msMedium[14].getWidth(title), Fonts.msMedium[12].getWidth(l1)) + 8;
float h = 24;
float x = 10;
float y = 10;
wtf.expensive.util.render.RenderUtil.Render2D.drawRect(x, y, w, h, 0x80000000);
Fonts.msMedium[14].drawString(stack, title, x + 4, y + 4, -1);
Fonts.msMedium[12].drawString(stack, l1, x + 4, y + 14, -1);
}
private void applyBaritoneOptimizations() {
var settings = BaritoneAPI.getSettings();
// Encourage breaking based on assumptions
double mult = 0.1; // default
if (optimizeEfficiency10.get() && optimize3x3.get()) {
mult = 7.0; // very fast mining through blocks
} else if (optimizeEfficiency10.get()) {
mult = 5.0;
} else if (optimize3x3.get()) {
mult = 3.0;
}
settings.avoidBreakingMultiplier.value = mult;
// Keep internal mining aggressive for corridor clearing
settings.forceInternalMining.value = true;
settings.internalMiningAirException.value = false;
settings.walkWhileBreaking.value = true;
settings.autoTool.value = true;
settings.considerPotionEffects.value = true;
}
private void resetBaritoneOptimizations() {
var settings = BaritoneAPI.getSettings();
settings.avoidBreakingMultiplier.value = 0.1; // default
settings.internalMiningAirException.value = true; // default
// others we can leave as defaults already true
}
private void fixPhantomsAround() {
BlockPos feet = mc.player.getPosition();
Direction face = mc.player.getHorizontalFacing();
BlockPos aheadFeet = feet.offset(face);
BlockPos aheadHead = aheadFeet.up();
tryFixPhantom(aheadFeet, face);
tryFixPhantom(aheadHead, face);
}
private void tryFixPhantom(BlockPos pos, Direction face) {
BlockState state = mc.world.getBlockState(pos);
boolean shapeEmpty = state.getCollisionShape(mc.world, pos).isEmpty();
boolean isAir = state.isAir();
if (isAir != shapeEmpty) {
try {
mc.player.connection.sendPacket(new CPlayerDiggingPacket(CPlayerDiggingPacket.Action.START_DESTROY_BLOCK, pos, face));
mc.player.connection.sendPacket(new CPlayerDiggingPacket(CPlayerDiggingPacket.Action.ABORT_DESTROY_BLOCK, pos, face));
} catch (Throwable ignored) {
}
}
}
}
Сразу пишу требуется Доработка (что-то может не работать)
Работает как баритон ищет вагонетки с сундуком если нету то либо копается либо ходит по миру ищет
Последнее редактирование: