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

Скачано и просмотрено: **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 профилей + дефолт), правится без пересборки:

```xml
<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.`

**Следующий заход**: роли танка и спойлера, покупка расходников у НПС, бегство к стражам от ПК, смена профессии на 20/40.

## Лицензии

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