Newton это часть клиента, которая ходит за тебя. Ты говоришь ему координаты, а он сам ищет дорогу и ведёт персонажа: обходит стены, прыгает, плавает, при необходимости прокапывает путь. Из игры им управляют командой .newton, из скрипта готовым объектом newton.
Кроме ходьбы он умеет летать на элитре, искать и копать блоки нужного типа, раскапывать и заполнять прямоугольную область.
mod = Module("GoHome", "Player")
mod.setKey(72) # H
@events.module_toggled
def on_toggle(event):
if event.getModule().getName() != "GoHome" or not event.isState():
return
newton.goto(120, 64, -340, radius=1) # пошли, дорогу он найдёт сам
mod.setEnabled(False)В один момент времени задача только одна. Новая отменяет предыдущую, поэтому вторая goto подряд это не две точки маршрута, а замена цели.
Точку можно задать тремя числами, списком или сущностью: у сущности координаты возьмутся сами. Дробные координаты округляются вниз, до блока.
newton.goto(100, 64, -200) # три числа
newton.goto([100, 64, -200]) # список или кортеж
newton.goto(world.nearest_player()) # прямо к игроку
newton.goto(100, 64, -200, radius=3) # достаточно подойти на 3 блока
newton.goto_xz(100, -200) # любая высота, лишь бы X и Z сошлись
newton.goto_y(12) # спуститься или подняться на высоту 12radius почти всегда стоит задавать. Дойти ровно на один конкретный блок получается не везде: цель может оказаться в стене, под водой или на краю обрыва. С запасом дорога находится чаще и быстрее.
| Вызов | Что делает |
|---|---|
newton.goto(точка, radius=0, elytra=False) | Идти к блоку. С radius достаточно подойти близко, с elytra полетит |
newton.goto_near(точка, radius=1) | То же самое, но радиус обязателен |
newton.goto_xz(x, z) | Прийти в колонку X и Z на любой высоте |
newton.goto_y(y) | Оказаться на нужной высоте |
newton.fly_to(точка, keep_y=True) | Лететь на элитре: сам взлетит и сам будет пускать фейерверки |
newton.cancel() | Остановить задачу и отпустить клавиши |
Все они возвращают True, если задача принята. Ложь означает, что клиент ещё не запустил Newton или блок в аргументе не существует. Ошибку они не бросают, скрипт от этого не падает.
fly_to это отдельный режим, а не ходьба по воздуху. Клиент взлетает сам, подкидывает себя фейерверками, облетает препятствия и в конце заходит на посадку.
newton.fly_to(1500, 120, -800) # лететь на высоту 120
newton.fly_to(1500, 120, -800, keep_y=False) # высоту держать свою
# то же самое, но через goto
newton.goto(1500, 120, -800, elytra=True)mine ищет ближайший блок нужного типа, подходит к нему, копает и подбирает то, что выпало. Потом берётся за следующий такой же. Имя блока пишется как в игре, приставку minecraft: можно опустить.
newton.mine("diamond_ore")
newton.mine("minecraft:ancient_debris")Область задаётся двумя противоположными углами, порядок углов неважен. excavate выносит внутри всё, fill наоборот заполняет пустоту блоком из инвентаря.
a = [100, 60, 200]
b = [110, 66, 210]
newton.excavate(a, b) # выкопать всё внутри
newton.excavate(a, b, "stone") # только камень
newton.fill(a, b, "cobblestone") # заполнить булыжникомТу же область можно выделить в игре, глядя на блок и набирая .newton sel два раза. Скрипт видит это выделение и умеет ставить углы сам.
newton.select(100, 60, 200) # первый угол
newton.select(110, 66, 210) # второй угол
area = newton.selection() # {"min": [...], "max": [...]} или None
if area is not None:
newton.excavate_selection() # раскопать выделенное
# newton.fill_selection("stone") # или заполнить
newton.clear_selection()О ходе работы Newton сообщает пятью событиями. Полное описание каждого лежит на странице событий.
| Событие | Когда приходит |
|---|---|
newton_started | Задача принята. getProcess() говорит какая |
newton_path | Дорога построена, getSteps() это её длина в шагах |
newton_node | Пройден шаг: координаты блока, номер шага и всего шагов |
newton_finished | Задача выполнена до конца |
newton_failed | Задача сорвалась или отменена, getReason() объясняет почему |
Самое полезное это цепочка задач: в newton_finished ставим следующую точку. Получается обход маршрута.
mod = Module("Patrol", "Player")
POINTS = [[100, 64, 200], [140, 64, 210], [180, 70, 190]]
state = {"i": 0}
def go_next():
if not mod.isEnabled():
return
point = POINTS[state["i"] % len(POINTS)]
state["i"] += 1
newton.goto(point, radius=1)
@events.newton_finished
def on_done(event):
go_next() # дошли, идём к следующей точке
@events.newton_failed
def on_fail(event):
if event.getReason() != "отменён":
client.warn("Патруль встал: " + event.getReason())
@events.module_toggled
def on_toggle(event):
if event.getModule().getName() != "Patrol":
return
if event.isState():
go_next()
else:
newton.cancel()Спросить, чем клиент занят прямо сейчас, можно в любой момент, например из tick или прямо при отрисовке HUD.
| Метод | Возвращает | Что это |
|---|---|---|
newton.ready() | bool | Newton запущен и принимает задачи |
newton.active() | bool | Прямо сейчас что-то выполняется |
newton.process() | str | None | Имя задачи: goto, mine, excavate, fill, elytra |
newton.status() | str | None | Строка состояния, та же что у .newton status |
newton.progress() | float | Доля пройденного пути, от 0.0 до 1.0 |
newton.path() | dict | None | Подробности маршрута: step, steps, next, goal |
newton.pause() / resume() / paused() | bool | Пауза и продолжение задачи |
newton.command(строка) | bool | Команда как в чате, но без точки: "goto 100 64 -200" |
newton.safewalk | bool | Не сваливаться с краёв блоков во время задачи |
newton.logging | bool | Писать ли отчёт Newton в чат |
el = Hud("Newton", icon="hud/player", width=110, height=22)
@el.render
def draw(ctx):
if not newton.active():
ctx.size(110, 22)
ctx.client_rect()
ctx.text("Newton спит", 8, 7, size=7)
return
path = newton.path()
text = newton.process() or "?"
if path is not None:
text = "%s %d/%d" % (text, path["step"], path["steps"])
ctx.size(110, 22)
ctx.client_rect()
ctx.text(text, 8, 7, size=7)
ctx.rect(0, 20, 110 * newton.progress(), 2, Color(120, 200, 255))