1.7.8378

C#-скрипты — Advanced — Ссылки на скрипты из BT/Макросов

Эта функция позволяет вам привязать из BT/макроса другую ауру, содержащую действие C# Script — это эквивалентно тому, как если бы вы «ссылались» на другой проект в программировании.
Все классы и типы, определённые в этом скрипте, станут доступны для использования в BT.

Механизм ссылок существует уже несколько месяцев, но ранее он был «спрятан» от глаз, так как был неполноценным и не работал так, как мне хотелось.

Ссылки


Зачем это нужно?

Теперь вы можете создать класс C#, который будет анализировать игру — через триггеры компьютерного зрения или напрямую читая память — и предоставлять BehaviorTree необходимые данные для принятия решений.
Вместо того чтобы загромождать дерево десятками переменных и проверок, вы просто создаёте один класс, например TheGame, который инкапсулирует всё получение информации.


Пример бота

Этот бот использует именно тот подход, который описан ниже. Он знает окружение, статы свои и окружающих монстров, может строить план действий и т.п. В целом в таком подходе ограничение я пока встретил только одно - свой собственный потолок.

Ссылка


Аура со скриптом внутри

Посмотрим на "Shared"-ауру и её файлы.

TheGame.cs

csharp
public sealed class TheGame {
    public TheGame(IFluentLog log){
        Log = log;
    }

    public IFluentLog Log {get;}

    public int IntValue { get; private set; }

    public void Refresh()
    {
        IntValue++; // в реальности здесь может быть чтение из памяти или обновление триггеров
        Log.Info($"Refreshed the state, value: {IntValue}");
    }
}

Класс готовит всё для логики: инициализация триггеров, чтение из памяти, создание OSD — всё, что нужно. Когда вызывается Refresh, происходит обновление состояния.


Script.csx

csharp
[Inject] IAuraTreeScriptingApi AuraTree {get; init;}

Log.Info("Bot is being started!");

var tree = AuraTree.GetBehaviorTreeByPath("./New tree");
var game = GetService<TheGame>();
tree["TheGame"] = game;

Так мы передаём объект TheGame в BT через переменные. Это ключевая часть, которая раньше отсутствовала. Теперь передаваемые через переменные объекты доступны полностью и без ограничений.


Behavior Tree

Пример структуры дерева: BT


Обновление данных

csharp
var game = Variables.Get<CheatCrescendo.TheGame>("TheGame").Value;
game.Refresh();

В этом узле вызываем Refresh, который обновляет состояние игры. Переменная "TheGame" к этому моменту уже инициализирована — либо скриптом, либо другой нодой.


Отрисовка OSD

csharp
return Run();

public IEnumerator<NodeStatus> Run(){
    using var osd = GetService<IOnScreenCanvasScriptingApi>().Create();

    var game = Variables.Get<CheatCrescendo.TheGame>("TheGame").Value;

    var textOsd = osd.AddHtmlObject();
    while (!cancellationToken.IsCancellationRequested){
        textOsd.Html = $"{game.IntValue}";
        yield return NodeStatus.Success;
    }
}

Это пример создания OSD, который визуализирует текущее значение IntValue. Используется новая возможность — IEnumerator<NodeStatus>, позволяющая "разбивать" жизненный цикл ноды. В первом запуске создаётся OSD, далее оно просто обновляется.


Логика игры

Под селектором можно размещать сколько угодно нод, проверяющих текущее состояние. Всё, что нужно — обращаться к TheGame и вызывать его методы.

Например, хотите получить HP напрямую из памяти? Напишите метод в TheGame — вызывайте его из BT-ноды. Нужна проверка по цвету через ColorSearch? То же самое. Даже движение между локациями можно вынести в метод: открыть портал, выбрать опцию, кликнуть — всё в TheGame, один вызов из BT.


Производительность

Добавлено множество улучшений, влияющих на производительность. Если заметите проблемы — сообщайте.


Исправления / Улучшения

  • [Behavior Trees] Прототип параллельной загрузки узлов — должно ускорить загрузку больших деревьев
  • [Scripting] Пространство имён PoeShared.Blazor.Controls, содержащее элементы управления, теперь доступно из скриптов по умолчанию