Секвенция

Невероятно мощная штука в ситуациях, когда Вам нужны инструменты для реализации скриптов с последовательным выполнением или таймером.

Находится он в level$sequence. Приведём пример на основе crafttweaker.api.event.entity.player.ItemPickupEvent.

Пример секвенции

import crafttweaker.api.event.entity.player.ItemPickupEvent;
import crafttweaker.api.events.CTEventManager;
CTEventManager.register<crafttweaker.api.event.entity.player.ItemPickupEvent>((event) => {
    var player = event.player;
    if (player.level.isClientSide) return;
    var level = player.level;
    var item = event.getStack();
    if (item.registryName == <item:minecraft:dirt>.registryName) level.sequence();
});

Сиквенцер создаётся просто, вдобавок в него можно поместить MapData, которая будет хранить какие-либо параметры.

level.sequence({version: "1.0.0"});

Но писать MapData необязательно, она может иметь пустое значение.

level.sequence();

Создадим такой код, который будет выдавать игроку через 100 ticks алмаз, если он подберёт землю.

level.sequence().addTask(new SleepTask(100)).run((player, context) => player.inventory.add(<item:minecraft:diamond>));

Для удобства объяснения я буду объяснять всё на уровне кода, а точнее по нижнему примеру. Давайте разбираться.

level.sequence().addTask(ISequenceTask<T,U>).run(BiConsumer<T,SequenceContext<T,U>>);

В методе addTask у нас во входных параметрах выступает ISequenceTask, в конструкторе которого есть T и U, они являются Objects, то есть любой объект, будь то int или передача собственного класса.

В самом craftTweaker есть самобытное задание - это SleepTask. У него есть метод tick, который имеет входные параметры T и SequenceContext<T,U>.

Вы можете вызывать sequence по завершении иного sequence. Для этого в метод tick мы должны передать level и SequenceContext и в него же передать наш sequnce по окончании которого запустится другой sequence и MapData, в которую будет записана информация для выполнения.

import crafttweaker.api.util.sequence.SequenceContext;
import crafttweaker.api.sequence.task.ISequenceTask;
import crafttweaker.api.data.MapData;

var sequence1 = level.sequence().addTask(new SleepTask(100)).run((player, context) => player.inventory.add(<item:minecraft:diamond>));
var task = new SleepTask(20).tick(level, new SequenceContext(sequence1, new MapData()));
if (task.isComplete()) {
    var sequence2=leve.sequence().addTask(new SleepTask(60)).run((player,context)=>player.sendMessage("Во работает"));
}

Секвенция невероятно сложная тема без внятной документации. Всё написанное здесь базируется на личном опыте журналиста.

В методе run во входных данных используется BiConsumer<T,U>: вместо U у нас SequenceContext<T,U>.

В T мы пишем любой Object, который хотим использовать. В нашем случае это player. Заместо SequenceContext<T,U> Вы можете написать какой-либо другой Object, но это не рекомендуется.

Т.е., Вы можете написать run((player, level) => {}), и оно будет работать. Но, если Вам понадобится SequenceContext, уже его получить не удастся.


InstantTask

Поговорим теперь про все Task, которые у нас существуют. Он выполняется немедленно, в отличие от SleepTask и SleepUntilTask.

import import crafttweaker.api.sequence.task.type.InstantTask;
level.sequence().addTask(new InstantTask((player, context) => player.sendMessage("Я выполняюсь мгновенно!")));

SleepUntilTask

В отличие от SleepTask, секвенция будет остановлена, пока условие не будет выполнено.

import crafttweaker.api.sequence.task.type.SleepUntilTask;
level.sequence().addTask(new SleepUntilTask((player, context) => player.inventory.contains(<item:minecraft:diamond>))).run((player, context) => player.sendMessage("Вау, у тебя есть алмаз !"));

Last updated