Нашёл вот такой скриптец. Копает, но что-то не то с паузой между копанием. То ждет что-то, то слишком быстро повторяет действие и по этому выходит "You stop mining".
Может кто-то, кто понимает глянет... Есть ли смысл мучать этот скрипт, либо искать другое что-то.
Заранее спасибо.
P.S. - Ультиму открыл сегодня за много лет, а Orion увидел вообще в первый раз. ![]()
///////////////////////////////////////////////////////////////////////////////////////////
//////////////////// -Mining for UORPG server (17.05.2017) by Hotride- ////////////////////
///////////////////////////// -Minimal OA version 2.0.7.0- ////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// -Настройка скрипта- ///////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
//
// Перед запуском требуется:
// 1) Настроить WayPoints - массив координат, на которых будут обкапываться тайлы вокруг
// персонажа. Желательно записывать их так, что бы персонаж раскапывал как можно больше
// тайлов пещеры, и не тратил много времени при перемещениями между точками.
// 2) Подготовка ресурсов.
// При разгрузке в банк (UnloadToBank): указать ResultContainer как серийник банка
// (_info на любую вещь в банке, C=0x... будет серийник банка), закинуть туда реги на
// реколл, инструменты, указать OreBag в нем (или, может быть равен ResultContainer).
// При разгрузке в контейнер у дома: указать его как ResultContainer, закинуть туда реги
// на реколл, инструменты, указать OreBag в нем (или, может быть равен ResultContainer).
// 3) Задать Tool (если нужно копать конкретным инструментом), указать ToolType для
// добора инструментов из ResultContainer, указать количество инструментов для добора
// ToolsCount.
// 4) Указать серийники рун или рунбук с дефолтными рунами (в дом RuneHomeSerial и в пещеру
// RuneCaveSerial), указать минимальное количество регов ReagentsCount, после которого
// добирать их из ResultContainer.
// 5) Настроить использование хайда UseHiding.
// 6) Настроить расстояние для обкопки DigDistanceX и DigDistanceY.
// 7) Если нужно игнорировать некоторые руды при копки (не продолжать копать, если такая руда
// попалась) то указать названия руды в IgnoreOreNames, либо оставить это поле пустым.
// 8) Если нужно сбрасывать какую-то руду после обкопки (или перед улетом домой) то
// указать цвета руды в DropOreColors, либо оставить это поле пустым.
// 9) Настроить лимит веса MaxWeight.
//
// Принцп работы скрипта:
// Запускаем непосредственно в пещере.
// Скрипт подходит к первой точке, обкапывает все тайлы вокруг на указанном расстоянии и
// переходит на следующую точку, повторяет до бесконечности (либо пока не убьют).
// При достижении лимита веса сбрасывает указанную руду на пол (под ноги), если перевес
// остался - летит на разгрузку и добор расходников.
// После этого - летит обратно в пещеру и идет на ту же точку, с которой улетел,
// продолжает обкопку.
//
///////////////////////////////////////////////////////////////////////////////////////////
//Чем будем копать (серийник объекта), если пустая строка - ищет ToolType
var Tool = 'pickaxe';
//Тип кирки/лопаты, чем копать, можно указать несколько типов
var ToolType = '0x0E85|0x0E86';
//Количество инструментов для добора
var ToolsCount = 0;
//Контейнер с мешком для руды (или просто для руды, если не нужно скидывать ее в мешок)
var ResultContainer = '0x409A986F';
//Контейнер, куда складывать руду (может быть равен ResultContainer, если для руды нет отдельного мешка в нем)
var OreBag = '0x409A986F';
//Разгрузка происходит в банк, true - да, false - разгружается в контейнер у дома (или где-то еще)
var UnloadToBank = false;
//Максимальный вес, при котором выкидывать лишнее из пака (если есть что-то лишнее), если вес не изменился - лететь домой разгружаться
var MaxWeight = Player.MaxWeight() - 10;
//Серийник руны в дом
var RuneHomeSerial = '0x4056158C';
//Серийник руны в перещу
var RuneCaveSerial = '0x4058675E';
//Текст физла заклинания
var FizzlesText = 'The spell fizzles';
//Сколько брать регов на реколл?
var ReagentsCount = 20;
//Текст удачной копки
var PutText = 'You put';
//Текст не удачной копки или режима вармода (если такое сообщение есть на сервере)
var FailText = 'You loosen some|thoughts of battle';
//Текст ошибки мининга (слишком далеко, не могу достать, сдох или что-то еще)
var StopText = 'There is nothing here to mine|Try mining|away|no line of|reach that|You cannot mine so|Where do you want|слишком далеко';
//Какую руду прекращать копать, если попалась
var IgnoreOreNames = '';
//Какую руду (цвета руды) сбрасывать на землю, когда обрыли все тайлы вокруг себя
var DropOreColors = '';
//Прятаться во время обкопки тайлов (true - прятаться, false - нет)
var UseHiding = false;
//Текст хайдинга
var HidingText = 'seem to hide|have hidden';
//Расстояние, на котором копать по X
var DigDistanceX = 2;
//Расстояние, на котором копать по Y
var DigDistanceY = 2;
//Список точек, на которых обкапывать тайлы вокруг себя
var WayPoints =
[
[2439, 94],
[2432, 91],
[2428, 87],
[2422, 90],
[2426, 95],
[2427, 101],
[2427, 106],
[2423, 109],
];
///////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////// -Глобальные переменные. Не изменять- //////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
//Склейка текстов, что представлены выше.
var SearchText = PutText + '|' + FailText + '|' + StopText;
//Указатель на текущую точку
var CurrentWayPoint = 0;
var CurrentMinDropX = 0;
var CurrentMaxDropX = 0;
var CurrentDropX = 0;
var CurrentMinDropY = 0;
var CurrentMaxDropY = 0;
var CurrentDropY = 0;
///////////////////////////////////////////////////////////////////////////////////////////
//Основная фукнция
function Mining()
{
//Роем бесконечно
while (true)
{
//Проходимся по списку точек
for (CurrentWayPoint = 0; CurrentWayPoint < WayPoints.length; CurrentWayPoint++)
{
var point = WayPoints[CurrentWayPoint];
//Пытаемся прийти на точку
if (WalkToPoint(point[0], point[1]))
{
//Пытаемся обкопать все вокруг себя
if (!MiningHere(point[0], point[1]))
{
//Завершаем скрипт, если что-то пошло не так (только для теста, в дальнейшем заменить на какое-то действие)
return;
}
}
}
//Обеспечение задержек в вечных циклах
Orion.Wait(100);
}
}
///////////////////////////////////////////////////////////////////////////////////////////
//Функция обкопки тайлов вокруг персонажа
function MiningHere(x, y)
{
//Сбрасываем вармод, если это необходимо
if (Player.WarMode())
{
Orion.WarMode(false);
Orion.Wait(100);
}
//Проход по квадрату
for (var x = -DigDistanceX; x <= DigDistanceX; x++)
{
for (var y = -DigDistanceY; y <= DigDistanceY; y++)
{
//Роем, если вернулось false - максимальный вес достигнут
if (!Dig(x, y))
{
Orion.Print(0x0022, 'Достигнут максимальный вес!');
return false;
}
Orion.Wait(100);
}
}
DropExtraOres();
return true;
}
///////////////////////////////////////////////////////////////////////////////////////////
//Функция получения серийника инструмента
function GetTool()
{
var obj = Orion.FindObject(Tool);
if (obj == null)
{
var list = Orion.FindType(ToolType, -1, self);
if (list.length)
return list[0];
else
{
list = Orion.FindType(ToolType);
if (list.length)
return list[0];
}
return '';
}
return obj.Serial();
}
///////////////////////////////////////////////////////////////////////////////////////////
//Функция выкапывания тайла
function Dig(x, y)
{
//Пока живы - роем
while (!Player.Dead())
{
//Прячемся
if (UseHiding && !Player.Hidden())
{
Orion.UseSkill('Hiding');
Orion.WaitJournal(HidingText, Orion.Now(), Orion.Now() + 7000, 'sys|my');
}
Orion.UseObject(toolSerial);
//Проверяем возможность наведения автотаргета на тайл
if (!Orion.ValidateTargetTileRelative('cave', x, y))
break;
var toolSerial = GetTool();
if (toolSerial == '')
{
Orion.Print('0x0021', 'Tool is not found!!!');
Orion.Wait(1000);
return false;
}
//Используем кирку и тыкаем со смещением относительно персонажа на тайл
Orion.WaitTargetTileRelative('cave', x, y, 0);
Orion.UseObject(toolSerial);
var msg = Orion.WaitJournal(SearchText, Orion.Now(), Orion.Now() + 15000, 'sys|my');
Orion.Wait(5000);
//Если сдохли - выходим из цикла
if (Player.Dead())
return false;
//Если максимальный вес достигнут - пытаемся сбросить лишнюю руду на пол
if (Player.Weight() >= MaxWeight)
{
DropExtraOres();
//Если это не помогло (запас веса 50) - летим разгружаться
if (Player.Weight() >= MaxWeight - 10)
RecallUnload();
}
if (msg != null)
{
var text = msg.Text();
//Если что-то упало в пак
if (Orion.Contains(text, PutText))
{
//Если это нечто - игнорируемая руда - выходим из цикла
if (Orion.Contains(text, IgnoreOreNames))
break;
}
else if (Orion.Contains(text, FailText)) //Дернем вармод при физле/сообщении о том, что мы в вармоде
Orion.WarMode(false);
else if (Orion.Contains(text, StopText)) //Если нельзя достать до тайла или тут больше нет руды - выходим
break;
}
Orion.Wait(100);
}
return true;
}
///////////////////////////////////////////////////////////////////////////////////////////
//Функция сброса предмета на землю, с проверкой на персонажа (под персонажей нельзя сбрасывать)
function DropGround(serial)
{
var obj = Orion.FindObject(serial);
if (obj == null)
return false;
var oldContainer = obj.Container();
//Проходимся по координатам
for (var x = CurrentDropX; x <= CurrentMaxDropX; x++)
{
for (var y = CurrentDropY; y <= CurrentMaxDropY; y++)
{
for (var i = 0; i < 3; i++)
{
Orion.Drop(serial, 0, x, y, Player.Z());
Orion.Wait('moveitemdelay');
if (oldContainer != obj.Container())
return true;
}
}
CurrentDropY = CurrentMinDropY;
}
CurrentDropX = CurrentMinDropX;
return false;
}
///////////////////////////////////////////////////////////////////////////////////////////
//Функция сброса лишней руды
function DropExtraOres()
{
//Если не указаны цвета руды - выходим
if (DropOreColors == '')
return;
//Максимальная дистанция дропа
var maxDropDistance = 1;
//Минимальные и максимальные координаты для дропа
CurrentMinDropX = Player.X() - maxDropDistance;
CurrentMaxDropX = Player.X() + maxDropDistance;
CurrentMinDropY = Player.Y() - maxDropDistance;
CurrentMaxDropY = Player.Y() + maxDropDistance;
CurrentDropX = CurrentMinDropX;
CurrentDropY = CurrentMinDropY;
//Крутим цикл, пока не сбросим всю руду
while (true)
{
//Поиск всех типов руды всех указанных цветов
var list = Orion.FindType('0x19B7|0x19BA|0x19B8|0x19B9', DropOreColors);
//Ничего не нашлось - выходим
if (!list.length)
break;
//Сбрасываем под ноги все что нашлось
for (var i = 0; i < list.length; i++)
{
if (!DropGround(list[i]))
return;
Orion.Wait(100);
}
Orion.Wait(100);
}
}
///////////////////////////////////////////////////////////////////////////////////////////
//Функция разгрузки
function UnloadOres()
{
if (UnloadToBank)
Orion.Say('bank');
else
Orion.UseObject(ResultContainer);
Orion.Wait(500);
if (ResultContainer != OreBag)
{
Orion.UseObject(OreBag);
Orion.Wait(500);
}
//Крутим цикл, пока не сбросим всю руду
while (true)
{
//Поиск всех типов руды всех указанных цветов
var list = Orion.FindType('0x19B7|0x19BA|0x19B8|0x19B9');
//Ничего не нашлось - выходим
if (!list.length)
break;
//Сбрасываем под ноги все что нашлось
for (var i = 0; i < list.length; i++)
{
Orion.MoveItem(list[i], 0, OreBag);
Orion.Wait('moveitemdelay');
}
Orion.Wait(100);
}
}
///////////////////////////////////////////////////////////////////////////////////////////
//Функция добора расходников
function ReloadConsumables()
{
var types = ['bp', 'bm', 'mr'];
for (var i = 0; i < types.length; i++)
{
var count = Orion.Count(types[i]);
if (count < ReagentsCount)
{
var list = Orion.FindType(types[i], '-1', ResultContainer);
if (!list.length)
{
Orion.Print('0x0021', 'Reagent is not found ' + types[i]);
continue;
}
Orion.MoveItem(list[0], ReagentsCount / 2);
Orion.Wait('moveitemdelay');
}
//Дополнительное время ожидания
Orion.Wait('moveitemdelay');
}
var list = Orion.FindType(ToolType);
if (list.length < ToolsCount)
{
var count = ToolsCount - list.length;
var list = Orion.FindType(types[i], '-1', ResultContainer);
if (!list.length)
Orion.Print('0x0021', 'Tool is not found ' + types[i]);
else
{
if (list.length < count)
count = list.length;
for (var i = 0; i < count; i++)
{
Orion.MoveItem(list[i]);
Orion.Wait('moveitemdelay');
}
//Дополнительное время ожидания
Orion.Wait('moveitemdelay');
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////
function Recall()
{
Orion.WalkTo( 2441, 94, 30, 0);
Orion.WalkTo( 2451,91, 30, 0);
}
function Recall2()
{
Orion.WalkTo( 2451, 91, 30, 0);
Orion.WalkTo( 2441, 94, 30, 0);
}
///////////////////////////////////////////////////////////////////////////////////////////
//Фукнция разгрузки
function RecallUnload()
{
//xodilka домой
Recall();
Orion.Wait(1000);
//Разгрузка
UnloadOres();
Orion.Wait(1000);
//Добор расходников
ReloadConsumables();
Orion.Wait(1000);
//xodilka обратно в перещу
Recall2()
//Проходимся по списку точек, возвращаемся на место, где стояли
for (var i = 0; i < CurrentWayPoint; i++)
{
var point = WayPoints[i];
//Пытаемся прийти на точку
WalkToPoint(point[0], point[1]);
}
}
///////////////////////////////////////////////////////////////////////////////////////////
//Функция ходилки, можно добавить сюда что-то еще
function WalkToPoint(x, y)
{
return Orion.WalkTo(x, y, 0, 0);
}
///////////////////////////////////////////////////////////////////////////////////////////





