Files
L2-SPP/BOTBRAIN.md
T

9.7 KiB
Raw Blame History

Что взять у чужих ботов (разбор исходников)

Скачано и просмотрено: L2jRoboto (серверные фантомы, GPL-3), SmartBot (наш прошлый референс, GPL-3), L2Bot2.0 (клиентская фармилка, C#, инъекция в клиент), L2NET (клиентский бот со своим скриптовым движком). Ничего не копируем построчно — берём модель поведения (см. «Лицензии» внизу).

Кто чем полезен

L2jRoboto — ближе всего к нашей задаче (он тоже поднимает Player на сервере). Полезное:

  • на каждый класс свой AI-класс со своим набором заклинаний: DuelistAI, CardinalAI, SaggitariusAI, SoultakerAI, ~20 классов;
  • заклинания описаны как данные с приоритетом: OffensiveSpell(345, 1), HealingSpell(1218, TARGET_ONE, 70, 3) — «лечить, когда цель ниже 70% HP», приоритет 3;
  • отдельные списки: атакующие / лечащие / self-support / бафы; выбирается первое доступное по приоритету;
  • шоты и стрелы подбираются по уровню (таблица уровень → грейд) и авто-подкачиваются;
  • смерть: N тиков лежит, потом «в деревню»;
  • ограничение: цель выбирается случайно в радиусе, никакой оценки опасности; фактически это красивая массовка.

L2Bot2.0 — настоящая фармилка, и вот тут «понимание игры». Полезное:

  • конечный автомат состояний: Dead → Idle → FindTarget → MoveToTarget → Attack → Rest → MoveToSpot с явными условиями переходов;
  • выбор моба по правилам: списки включённых/исключённых id, ограничение по разнице уровней (MobLevelLowerLimit/UpperLimit), проверка перепада высоты (MobsMaxDeltaZ, чтобы не бить недосягаемых), проверка «внутри зоны фарма»;
  • скиллы по условиям: SkillCondition { id, MaxTargetPercentHp, MinPlayerPercentMp, MaxPlayerPercentHp } — то есть «добивание только когда цель ниже X%», «не кастовать, если мало МП»;
  • отдых: сесть при HP/MP ниже порога, встать при достижении верхнего порога — сидя реген в разы быстрее;
  • дистанция боя зависит от оружия (лук/ближний) и от дальности выбранного скилла;
  • приоритет спойла и свипа, счётчики попыток;
  • подбор лута с фильтрами и радиусом;
  • возврат на спот, если ушёл далеко.

L2NET — интересен своим скриптовым движком (условия/циклы поверх пакетов), но для нас это оверкилл.

Чего не хватает нашим ботам (итог)

Механика У нас Откуда берём
Скиллы по условиям (HP цели, МП, приоритет) нет, только автоатака L2Bot2 SkillCondition + Roboto Spell-списки
Наборы скиллов по классам нет Roboto (AI на класс)
Отдых сидя при низком HP/MP нет L2Bot2 RestState
Выбор моба по уровню/высоте/зоне берём ближайшего L2Bot2 Helper.GetMobsToAttackByConfig
Дистанция боя по оружию и скиллу нет L2Bot2 GetAttackDistanceByConfig
Самобаф и поддержание бафов нет Roboto applyDefaultBuffs
Шоты по грейду + автопополнение грейд есть, автопополнения нет Roboto handleShots
Бегство при низком HP, страх ПК нет своё
Роли в пати (хил/баф/танк/спойл) нет Roboto (IHealer) + L2Bot2 (spoil/sweep)

План: BotBrain

Дерево приоритетов, каждый тик сверху вниз, первое сработавшее выигрывает:

  1. Мёртв → лежать, через N сек в деревню, вернуться на спот.
  2. Выживание → HP < 30%: хилка/скилл лечения; HP < 15% и рядом враг: бежать в город/к стражам.
  3. Обслуживание → нет бафов: бафнуть; нет шотов: докупить; HP/MP < порога и никого рядом: сесть отдыхать.
  4. Роль в пати → хилер лечит самого раненого, бафер обновляет бафы, танк держит агро.
  5. Бой → скилл по условиям (дебафф → бурст → добивание), иначе автоатака; держать дистанцию по оружию.
  6. Лут → подобрать свой дроп рядом.
  7. Фарм → выбрать моба (уровень ±, высота, зона), подойти, атаковать.
  8. Безделье → маршрут по зоне, болтовня, торговля.

Наборы скиллов держим данными (XML), а не кодом: <class id="88" role="fighter"><offensive id="261" priority="1" maxTargetHp="100"/><self id="139"/></class> — можно править без пересборки, как швы.

Что уже сделано (первая итерация)

FakePlayerBrain — дерево приоритетов, работает раньше «бытовой» логики (торговли, маршрутов), поэтому бот не пойдёт торговать, пока его бьют:

  1. Выживание: HP < 55% — лечащий скилл; < 40% — хилка (раз в 15 сек); < 25% и рядом враг — бегство в противоположную сторону на 12 секунд.
  2. Обслуживание: HP < 45% или MP < 35% и никого рядом — сесть отдыхать (встаёт на 85% HP / 75% MP); раз в 3 минуты обновить самобафы.
  3. Роль в пати: хилер лечит самого раненого соклановца в радиусе 900, если у того ниже 75% HP.
  4. Бой: скилл выбирается по условиям из XML (приоритет, maxTargetHp для добивания, minMp), проверяется кулдаун, МП и дальность каста; лучники и маги отходят, если враг ближе 250, бойцы наоборот сближаются.
  5. Фарм: цель выбирается с умом — разница уровней не больше 8, перепад высоты меньше 200 (чтобы не долбиться в недосягаемого), не рейд, не чужая цель.

data/FakePlayerCombat.xml — наборы скиллов по классам (13 профилей + дефолт), правится без пересборки:

<class id="2" role="fighter" name="Gladiator">
    <offensive id="261" priority="1" maxTargetHp="100" minMp="20" />
    <offensive id="1"   priority="3" maxTargetHp="100" minMp="10" />
    <self id="8" />
</class>

role (fighter / archer / mage / healer / support) задаёт дистанцию боя и приоритеты.

Проверка: do=brain&name=Ник — покажет роль, HP/MP и какие скиллы из профиля бот реально выучил (+ есть, - нет). Плюс do=gear — что надето и штраф экспертизы.

Не проверено вживую: песочница в этот раз убивала процессы, поэтому сборка чистая (BUILD SUCCESSFUL), но запуск с ботами не прогнан. Первым делом посмотри logs -f game на строку FakePlayerCombatData: Loaded combat profiles for 13 classes.

Заход 03.09 (SPP 3) — сделано: спойлер (спойл + свип), покупка расходников и продажа хлама (FakePlayerEconomy), смена профессии на 20/40/76, бижа и городские бафы, ответный удар нападающему, поводок к споту, выбор одиночного моба не выше уровня+1, отдых при HP < 60 %, зелья через обработчик предметов, лут в мозге. Не сделано: роль танка (агро-скиллы), бегство к стражам от ПК.

Лицензии

L2jRoboto и SmartBot под GPL-3, L2Bot2.0 — тоже открытый. Мы не копируем их код, а реализуем поведение заново поверх Mobius. Это важно, если когда-нибудь захочешь выложить пак: копирование GPL-кода потребовало бы открыть исходники всей сборки.