macro
С этим плагином Вы сможете написать последовательность команд (макросов), которые бот будет выполнять вручную или в зависимости от ситуации (условия). Последняя версия - 2.0.3.
Установка
- Скачайте Macro plugin. Вы можете взять его тут или из SVN.
- Перейдите в папку OpenKore (которая содержит файл openkore.pl) и создайте новую папку plugins, если её ещё там нет.
- В архиве с макро-плагином вы найдёте файл macro.pl и папку Macro. Распакуйте их в папку с плагинами - plugins.
- В папке control создайте пустой текстовый файл macros.txt. В этот файл вы будете помещать ваши макросы и автомакросы.
После установки дерево папок OpenKore должно выглядеть примерно так (не считая файлов самой OpenKore):
openkore |-- openkore.pl |-- control | |-- macros.txt |-- fields |-- logs |-- plugins | |-- Macro | | |-- Automacro.pm | | |-- Data.pm | | |-- Parser.pm | | |-- Script.pm | | |-- Utilities.pm | |-- macro.pl |-- src |-- tables
Консольные команды
Синтаксис
macro <имямакроса> [опции] [-- параметр(ы)]
Запускает макрос <имямакроса>.
Опции
Опция | Значение | Описание |
---|---|---|
-repeat | n | повторяет макрос n раз |
-overrideAI | нет | отключает искуственный интеллект OpenKore |
-macro_delay | n | устанавливает задержку между командами макроса в n секунд, игнорируя значение macro_delay в файле timeouts.txt |
-exclusive | нет | не позволит автомакросу прервать выполнение этого макроса |
-orphan | <метод> | использует <метод> (terminate, reregister или reregister_safe) для обработки одиночного макроса |
Параметры Параметры для макроса определяются после двойного тире (--). Эти параметры будут доступны в теле макроса через переменные $.param1, $.param2 и т.д. Например:
macro foo { log Parameter 1 is $.param1 log Parameter 2 is $.param2 }
Если набрать в консоли macro foo -- foo bar то макрос выведет
[macro] Parameter 1 is foo [macro] Parameter 2 is bar
Консольные команды
- macro list
- Показывает список всех доступных макросов.
- macro stop
- Останавливает текущий макрос.
- macro pause
- Приостанавливает запущенный макрос.
- macro resume
- Включает приостановленный макрос.
- macro version
- Выводит на экран версию макроплагина.
- macro reset [<имямакроса(ов)>]
- Сбрасывает "run-once" всех автомакросов или определённого автомакроса. Эту команду можно использовать для нескольких автомакросов сразу. Для этого имена автомакросов пишутся через пробел.
- macro status
- Показывает запущен ли какой-лиюо макрос в настоящее время. Если макрос запущен, то показывает:
status: running << запущен delay: 10s << задержка перед следующей командой line: 3 << текущая строка макроса override AI: no << настройка опции "-overrideAI" paused: no << поставлен ли марос на паузу finished: no << закончен ли макрос
Конфигурационные файлы
- control/macros.txt
- Пишите ваши макросы и автомакросы в этом файле. Вы можете изменить имя файла в параметре конфига macro_file. Внимание: если у вас в этом файле содержится русский текст, то файл необходимо сохранить в кодировке utf-8 и закомментировать первую строчку знаком #.
- control/timeouts.txt
- В этот файл добавьте параметр macro_delay и напишите, сколько секунд будет длиться пауза между командами в теле макроса. Например, задержка в одну секунду: macro_delay 1
- control/config.txt
Параметр | Значение | Описание |
---|---|---|
macro_nowarn | 0 1 |
0 или 1 - вкл. или выкл. раздражающие предупреждения когда автомакрос не использует команду call |
macro_orphans | terminate reregister reregister_safe |
переопределяет поведение ИИ openkore в отношении "одиночных макросов". |
macro_file | имя файла | содержащий макросы файл (по умолчанию "macros.txt") |
macro_allowDebug | 0 1 |
console-check also processes openkore's debug messages (по умолчанию выкл: 0). Внимание: Затормаживает плагин. |
Синтаксис макроса
macro MacroName { do this.. and that.. yattayatta.. }
Имя макроса должно начинаться с латинской буквы, может содержать цифры и знак подчеркивания "_", но не может содержать знак пробела " ". Следите, чтобы макросы не назывались одинаково. Все консольные команды Openkore могут быть использованы в макросе - Console Commands.
- do <команда>
- Выполняет консольную <команду>. Список команд консоли Console Commands.
macro foo { do move 123 234 prontera do sit do c hello world }
- log <текст>
- Выводит <текст> на консоль.
macro foo { log This line logs a text to console. log All your base are belong to us! }
- pause [<n>]
- Останавливает макрос на n секунд.
macro foo { log It's 10:00:00 pause 10 log Now it's 10:00:10 log 10 seconds have passed after the first print. }
- call <имямакроса> [<n>]
- Вызывает макрос с именем <имямакроса> <n> раз (n – целое число). Когда макрос <имямакроса> закончится, то текущий макрос продолжит работу.
- release (<имяавтомакроса> | all)
- Освобождает закрытый автомакрос, позволяя ему еще раз сработать, если выполнятся условия его срабатывания. Автомакрос мог быть закрыт условием "run-once 1" или командой "lock <имяавтомакроса>". Команда release all освобождает все закрытые в данный момент автомакросы.
- lock (<имяавтомакроса> | all)
- Закрывает автомакрос <имяавтомакроса> и выключает проверку условий срабатывания, не позволяя таким образом ему выполнится. Команда lock all закрывает все автомакросы.
- stop
- Немедленно прерывает выполнение текущего макроса.
- set <опция> <значение>
- Устанавливает <опции> соответствующее <значение>:
- orphan <метод>
- macro_delay <задержка>
- overrideAI [0|1]
- repeat <числораз>
- exclusive [0|1]
Создание и работа с переменными
Вы можете создать и работать со своими собственными переменными в теле макроса. Имя переменной начинается со знака доллара "$" и может содержать латинские буквы и цифры. Чтобы создать переменную или присвоить ей новое значение, используйте операцию присваивания: $<имя переменной> = <значение> Чтобы обратиться к значению переменной, надо написать её имя, например $variable.
macro Hello { $var = Hello $var1 = World! log $var $var1 }
На консоль выведется сообщение:
[log] Hello World!
Если командой log вы хотите вывести символ доллара "$", то вам следует использовать символ обратная косая черта "\". Например так "\$":
macro money { log I have a lot of \$ }
Для увеличения или уменьшения значения переменной на 1, используйте:
$<имяпеременной>++ или $<имяпеременной>--
macro Counter { $counter = 0 log Counter is at $counter $counter++ log Now it's $counter $counter-- log It's back to $counter }
На консоли выведется:
log Counter is at 0 log Now it's 1 log It's back to 0
Вы можете удалить созданную вами переменную присвоив ей значение 'undef' или 'unset', например:
$x = 1 log \$x is $x $x = undef # or you can use 'unset' log \$x now vanished: $x
Для складывания двух переменных, а также для других операций над переменными следует использовать @eval , например:
macro math { $num = 2 $num2 = 3 $result = @eval($num+$num2) log $num + $num2 = $result }
На консоли выведется:
log 2 + 3 = 5
Можно использовать @eval внутри другого @eval, например:
macro math { $num = 2 $num2 = 3 $result = @eval(@eval($num+$num2) - @eval($num+$num2)) log ($num + $num2) - ($num + $num2) = $result }
Оператор | Описание |
---|---|
+ | Сложение |
- | Вычитание |
* | Умножение |
/ | Деление |
Допустим, переменной $list присвоено значение - строка, слова, разделенные запятыми. Тогда из этой строки можно сделать список слов, разделенных запятыми. После этого можно узнать первый элемент списка, как в следующем примере:
macro foo { $list = banana, apple, strawberry, grape $var = [$list] log The first element of \$list is $var log Now \$list contains $list }
На консоли выведется:
log The first element from $list is Banana log $list contains apple, strawberry, grape
Напоминание: Имена переменных состоят лишь из латинских букв и цифр.
Вложенные переменные
Можно создать "динамические" или так называемые "вложенные переменные". То есть имя одной и той же переменной может изменяться на протяжении макроса. Например, обычная переменная выглядит так: $a = "hello" А вот так выглядит вложенная переменная: ${$a} = "world" Здесь $a хранит в себе имя вложенной переменной. Т.е. вложенной переменной с именем hello присвоено значение world.
Пример 1:
macro foo { $name = Camila ${$name} = Brazil # Note: ${name} is equal to $Camila now log $name lives on ${$name} }
На консоль выведется:
log Camila lives on Brazil
Пример 2:
macro hh { $var = foo log $var ${$var} = bar log ${$var}
log Создадим массив из 10 элементов, присвоим им случайные числа от 1 до 20. $i = 0 :zikl $i++ ${$i} = @rand(1,20) log $i ${$i} if ($i < 10) goto zikl
log Выводим элементы массива и их значения задом наперед. $i = 11 :zikl2 $i-- log $i ${$i} if ($i > 1) goto zikl2
}
На консоль выведется:
[macro log] foo [macro log] bar [macro log] Создадим массив из 10 элементов, присвоим им случайные числа от 1 до 20. [macro log] 1 19 [macro log] 2 19 [macro log] 3 20 [macro log] 4 20 [macro log] 5 4 [macro log] 6 6 [macro log] 7 20 [macro log] 8 8 [macro log] 9 13 [macro log] 10 9 [macro log] Выводим элементы массива и их значения задом наперед. [macro log] 10 9 [macro log] 9 13 [macro log] 8 8 [macro log] 7 20 [macro log] 6 6 [macro log] 5 4 [macro log] 4 20 [macro log] 3 20 [macro log] 2 19 [macro log] 1 19
Специальные переменные
Есть специальные предопределенные макро-плагином переменные, их имена начинаются с символов доллара и точки: "$.". Они доступны только на чтение.
- $.map - карта, на которой вы находитесь ("prontera")
- $.pos - координаты вашей текущей позиции ("123 234")
- $.time - текущее время в unix-формате ("1131116304")
- $.datetime - текущее число и время ("Fri Nov 4 15:59:36 2005")
- $.hour - час
- $.minute - минута
- $.second - секунда
- $.hp - hp, жизнь
- $.sp - sp, мана
- $.lvl - базовый левел персонажа
- $.joblvl - джоб левел персонажа
- $.spirits - количество сферок у монка или монеток у ганса
- $.zeny - зеньги
- $.status - список статусов персонажа, через запятую
- $.paramN - параметры, с которым был запущен макрос из консоли OpenKore (смотри Commands)
- $.caller - имя сработавшего автомакроса, который запустил на выполнение текущий макрос
- $.weight - вес инвентаря персонажа
- $.maxweight - максимальная грузоподъемность персонажа
Специальные ключевые слова
Специальные ключевые слова начинаются со знака "@", возвращают значение в зависимости от переданных в скобках параметров.
- @npc (<x> <y> | /regexp/i | "<name>")
- Возвращает ID неписи, которая находится по координатам <x> <y> или имя неписи совпадает с шаблоном regexp или именем неписи является <name>. Возвращает -1 если не было найдено подходящей неписи.
- @inventory (<item>)
- Возвращает ID вещи <item> в инвентаре. Если вещи <item> нет, возвращает -1.
- @Inventory (<item>)
- Также как и @inventory возвращает ID вещи <item> в инвентаре. Но если таких вещей в инвентаре несколько, то возвращает ID всех вещей списком, разделяя ID запятыми. Если нет такой вещи в инвентаре, возвращает -1.
- @invamount (<item>)
- Возвращает количество вещей <item> в инвентаре.
- @cart (<item>)
- Возвращает ID вещи <item> в телеге. Если вещи <item> нет, возвращает -1.
- @Cart (<item>)
- Также как и @cart возвращает ID вещи <item> в телеге. Но если таких вещей в инвентаре несколько, то возвращает ID всех вещей списком, разделяя ID запятыми. Если нет такой вещи в телеге, возвращает -1.
- @cartamount (<item>)
- Возвращает количество вещей <item> в телеге.
- @storage (<item>)
- Возвращает ID вещи <item> на складе. Если вещи <item> нет, возвращает -1.
- @Storage (<item>)
- Так же как и @storage возвращает ID вещи <item> на складе. Но если таких вещей несколько, то возвращает ID всех вещей списком, разделяя ID запятыми. Если нет такой вещи на складе, возвращает -1.
- @storamount (<item>)
- Возвращает количество <item> на складе.
- @player (<name>)
- Возвращает ID игрока <name>. Если игрока <name> не видно, возвращает -1.
- @vender (<name>)
- Возвращает ID продавца <name>. Если продавца <name> не видно, возвращает -1.
- @store (<name>)
- Возвращает ID вещи <name> в магазине неписи. Если вещи <name> в списке товаров нет, возвращает -1.
- @shopamount (<item>)
- Возвращает количество вещей <item> в магазине.
- @random ("<argument1>", "<argument2>", ...)
- Возращает случайным образом один из перечисленных в скобках аргументов.
- @rand (<n>, <m>)
- Возвращает случайное число в диапазоне от <n> до <m> включительно.
- @eval (<argument>)
- Оценивает, вычисляет значение аргумента <argument>. Например, если "$v = 8", то результатом оператора "@eval ($v + 2)" будет число 10.
- @arg ("<argument>", <n>)
- Возвращает <n>-ое слово из строки "<argument>". Слова в строке разделяются знаками: ,.:;\"\'!?\r\n. Если <n> больше количества слов в строке, то возвращается пустая строка. Аргумент <n> может быть как целым числом, так и целочисленной переменной. Например:
- log @arg("aa, bb cc.dd",2)
- $n = 3
- log @arg("aa ! bb : cc . dd",$n)
- @config (<variable>)
- Возвращает значение параметра <variable> в конфиге config.txt.
- @venderitem (<name>)
- Возвращает ID вещи <name> в магазине игрока. Если вещи <name> в магазине игрока нет, возвращает -1.
- @venderprice (<indexID>)
- Возвращает цену вещи с ID <indexID> в магазине игрока.
- @nick (<word>)
- Escapes all the regexp metacharacters and some of the perl special characters with \ (a backslash). Especially for player's name.
Цепочка команд
Несколько команд выполняются друг за другом без задержки, если они объединены в цепочку команд квадратными скобками [ и ].
0 macro foo { 1 do whatever 2 log yet another line 3 [ 4 do something 5 do something else 6 log foo 7 ] 8 log done 9 }
Строка 3 начинает цепочку команд и сама по себе не вносит никакой задержки. Строки 4, 5 и 6 выполняются сразу же, как только предыдущая команда завершится. В цепочке команд нет задержек и выполнение команд не может быть прервано. Строка 7 завершает цепочку команд и строка 8 будет выполнятся через положенную задерку в $macro_delay секунд.
Подстроки
Вместо использования по одной команде на строку, можно отделять команды между собой символом точки с запятой ";" и располагать их в одной строке. Таким образом можно сократить количество строк, особенно при использовании операций присвоения ($var = 1, ${$var} = 2), инкрементации (++), декрементации (--) и других (set, lock, release, log, pause, do). Подробнее: Forums
Пример:
macro foo { $i = 1; pause 5; log \$i = $i; $ii = 2; $iii = 3; $i++; $ii--; lock automacroName; release automacroName; set overrideAI 1 }
Разделенные точкой с запятой ";" команды не будут иметь задержки, совсем прям как в цепочке команд, за исключением некоторых команд, таких как pause и log.
Условия
В макросах (например в операторе if) можно использовать следующие условия:
< меньше чем ... <= меньше либо равно == равно > больше чем ... >= больше или равно != не равно ~ содержится (<левая переменная> это элемент <правой переменной>, здесь правая переменная представляет собой лист переменных (см. пункт 6.1)
Оператор | Описание |
---|---|
< | меньше |
<= | меньше либо равно |
== | равно |
> | больше |
>= | больше либо равно |
!= | не равно |
~ | <леваячасть> есть элемент <праваячасть>, где <праваячасть> список, разделенный символом запятой "," |
=~ | проверяет регулярное выражение regexp. Подробнее: Forums |
arg .. arg2 | входит в диапазон значений между arg и arg2, где arg число, процент или переменная. |
Управление потоком и метки
Все высокоуровневые языки программирования, имея конструкции типа "if .. else", "while", "foreach", "for .. next", "do .. while" и вызов подпрограмм, сводятся к трём словам "if", "goto" и "while". Именно поэтому макро-плагин имеет только эти три ключевых слова. Так как нету видимой нумерации строк, для оператора goto требуются метки в теле макроса ":<имяметки>".
Оператор IF
Сейчас оператор if в макроплагине очень близок к perl-овому оператору if. Оператор if может принимать неограниченное количество выражений, разрешено использование регулярных выражений regexp, вместо and можно использовать && - логическое И, вместо or можно использовать || - логическое ИЛИ.
Синтаксис оператора IF
Можно использовать простое выражение;
if (arg1 <Conditions> arg2) (goto <label> | call <macro> [<n>] | stop)
Можно использовать простое выражение с уловием OR;
if (arg1 <Conditions> arg2 || arg3 <Conditions> arg4) (goto <label> | call <macro> <n> | stop)
Можно использовать простое выражение с уловием AND;
if (arg1 <Conditions> arg2 && arg3 <Conditions> arg4) (goto <label> | call <macro> <n> | stop)
Можно использовать простое выражение с обоими условиями OR и AND;
if ((arg1 <Conditions> arg2 || arg3 <Conditions> arg4) && arg5 <Conditions> arg6) (goto <label> | call <macro> <n> | stop) if ((arg1 <Conditions> arg2 && arg3 <Conditions> arg4) || arg5 <Conditions> arg6) (goto <label> | call <macro> <n> | stop) if ((arg1 <Conditions> arg2 && arg3 <Conditions> arg4) || (arg5 <Conditions> arg6 && arg7 <Conditions> arg8)) (goto <label> | call <macro> <n> | stop) if ((arg1 <Conditions> arg2 || arg3 <Conditions> arg4) && (arg5 <condition> arg6 || arg7 <condition> arg8)) (goto <label> | call <macro> <n> | stop)
- Notice inside of each brackets containing the AND and OR symbols.
Где;
- arg может быть переменной, вложенной переменной, специальным ключевым словом (@xxx), специальной переменной ($.xxx), @eval, буквами и цифрами или даже perl'овой функцией Perl Subroutines.
- <label>, имя существующей метки, может состоять только из латинских букв и цифр.
- <macro>, имя существующего макрос.
- <n>, сколько раз подряд должен отработать макрос.
Заметка:
- Если <n> равно нулю 0 или даже неопределено undefined, вызванный макрос запустится один раз и остановится, после чего вызвавший его макрос прекратит свою работу.
- Если <n> больше нуля 0, вызванный макрос будет запущен n раз подряд, после чего вызвавший его макрос продолжит свою работу.
Заметка²: В операторе IF можно использовать такое количество выражений, сколько необходимо.
if (arg1 <Conditions> arg2 || arg3 <Conditions> arg4 || ... || argN <Conditions> argN+1) (goto <label> | call <macro> <n> | stop)
Где;
- arg может быть переменной, вложенной переменной, специальным ключевым словом, @eval или буквами и цифрами.
- All the conditions is up to the Nth argument <Conditions> N+1th argument.
- While N is an integer number/s which is greater than zero.
Примеры
macro checknum { $num = @rand(1, 3) if ($num == 1) goto one if ($num == 2) goto two if ($num == 3) goto three :one log \$num is 1 stop :one log \$num is 2 stop :one log \$num is 3 stop }
Вышеописанный макрос выведет в консоль \$num is 1 если $num == 1, \$num is 2 если $num == 2, \$num is 3 если $num == 3. Такого же эффекта можно достичь, используя call вместо goto.
macro checknum { $num = @rand(1, 3) if ($num == 1) call one if ($num == 2) call two if ($num == 3) call three } macro one { log $num is 1 } macro two { log $num is 2 } macro three { log $num is 3 }
Более сложный макрос:
macro if { $i = 1 log \$i = $i if (((($i = 1 || $i < 5 || $i ~ 0 .. 5) && @eval(@eval($i - 1) - @eval($i - 0)) = -1) && ($i != 2 && $i > 0 && @eval($i - 1) = 0) && ($i != 2 && $i > 0 && @eval($i - 1) = 0)) && $i = 1) goto somewhere if (($i = 1 || $i < 5 || $i ~ 0 .. 5) && ($i != "" && $i > 0 && @eval($i - 1) = 0)) goto somewhere if (@eval (@eval($i-1) - 1) != "") goto somewhere if ((($i = 1) || ($i < 5 && $i ~ 0 .. 5)) && ($i != "" && $i > 0 && @eval($i - 1) > 0)) goto somewhere log ko stop :somewhere log OK }
Цикл по условию WHILE
В макросе while означает, что некоторые команды могут выполнится при определенных условиях несколько раз подряд, в цикле.
Синтаксис оператора WHILE
while (arg <condition> arg) as <loop> do bla bla ... end <loop>
Где;
- arg может быть переменной, вложенной переменной, специальным ключевым словом, @eval или буквами и цифрами.
- <loop> - название цикла.
Условия Conditions.
Пример
macro while { $i = 0 while ($i < 10) as loop log \$i = $i $i++ end loop }
На консоль выведется
log \$i = 0 log \$i = 1 log \$i = 2 log \$i = 3 log \$i = 4 log \$i = 5 log \$i = 6 log \$i = 7 log \$i = 8 log \$i = 9
Автомакросы
Автомакрос содержит условия, при удовлетворении всех заданных условий начинает работать связанный с автомакросом макрос.
Синтаксис
При выполнение всех условий вызывается макрос <macro>.
automacro <name> { <conditions> <values> call <macro> }
При выполнении всех условий макрос не вызывается, но выполняются команды <commands> в фигурных скобках
automacro <name> { <condition> <values> call { <commands> } }
Второй вариант полезен, если тело макроса не занимает много места, и нет нужды оформлять его отдельно. Первый вариант синтаксиса полезен, если вы хотите чтобы несколько автомакросов вызывали один и тот же макрос. Например:
automacro First { <conditions> call print } automacro Second { <conditions> call print } macro print { log $.caller triggered }
Условия в автомакросе
Автомакрос нуждается как минимум в одном условии или он никогда не сработает. В автомакросе может быть столько условий, сколько вы пожелаете. Некоторые условия устанавливают значения специальны переменных, которые вы потом можете использовать внутри макроса.
- map <mapname>
- Сработает, если текущая локация <mapname>.
- location [not] <mapname [<x1> <y1> [<x2> <y2>]] [, ...]
- Сработает, если текущая позиция [не] та, что указана в условии.
- Если координаты <x1> <y1> и <x2> <y2> не заданы, то автомакрос будет запускаться, как и в случае map <mapname>.
- Если указаны только координаты <x1> <y1>, то автомакрос запустится, если находясь на локации <mapname>, вы попадёте на координаты <x1> <y1>.
- Если указаны координаты <x1> <y1> и <x2> <y2>, то автомакрос запустится, если находясь на локации <mapname>, вы попадёте в мнимый прямоугольник, где <x1> <y1> - верхняя левая точка, а <x2> <y2> - нижняя правая точка.
Код: <x1> <y1> _______
| | | | |_______| <x2> <y2>
Отмечу, что <x1> < <x2> и <y1> > <y2> .
- Отделённые запятыми аргументы определяются как условие OR (или):
Код:
location geffen, prontera 123 234
- автомакрос будет запускаться, если Вы будете находиться в geffen или в prontera на координатах (123 234).
- Несколько строк определяются как условие AND (и):
Код:
location not geffen location not prontera
- автомакрос будет запускаться, если вы находитесь вне geffen и вне prontera.
- mapchange ( <mapname> | any | * ) [, ...]
- Triggers when changing map to <mapname>. If the argument is any or * (asterisk or star) then it triggers on any map change.
- Comma-separated arguments are treated as OR conditions.
- hp <condition> <amount>[%]
- Triggers when your hp matches the defined condition.
- Multiple lines are treated as AND Conditions.
- sp <condition> <amount>[%]
- Triggers when your sp matches the defined condition.
- Multiple lines are treated as AND conditions.
- spirit <condition> <amount>
- Triggers when your spirits match <condition> <amount>.
- Multiple lines are treated as AND conditions.
- weight <condition> <amount>[%]
- Triggers when your weight matches <condition> <amount> (absolute value) or <condition> <amount> percent (relative value).
- Multiple lines are treated as AND conditions.
- cartweight <condition> <amount>[%]
- Triggers when your cart weight matches <condition> <amount> (absolute value) or <condition> <amount> percent (relative value).
- Multiple lines are treated as AND conditions.
- zeny <condition> <amount>
- Triggers when your zeny amount matches <condition> <amount>.
- Multiple lines are treated as AND conditions.
- soldout <condition> <slots>
- Triggers when the amount of sold out item slots in your shop matches <condition> <slots>.
- Multiple lines are treated as AND conditions.
- status [not] <status> [, ...]
- Triggers when you are [not] <status>.
- The statuses "dead" and "muted" are supported additionally.
- Comma-separated arguments are treated as OR conditions.
- Multiple lines are treated as AND conditions.
- inventory "<item>" <condition> <amount> [, ...]
- Triggers when you have <condition> <amount> of <item> in your inventory.
- Comma-separated arguments are treated as OR conditions.
- Multiple lines are treated as AND conditions.
- storage "<item>" <condition> <amount> [, ...]
- Triggers when you have <condition> <amount> of <item> in your storage.
- Comma-separated arguments are treated as OR conditions.
- Multiple lines are treated as AND conditions.
- cart "<item>" <condition> <amount> [, ...]
- Triggers when you have <condition> <amount> of <item> in your cart.
- Comma-separated arguments are treated as OR conditions.
- Multiple lines are treated as AND conditions.
- shop "<item>" <condition> <amount> [, ...]
- Triggers when you have <condition> <amount> of <item> in your shop.
- Comma-separated arguments are treated as OR conditions.
- Multiple lines are treated as AND conditions.
- base <condition> <level>
- Triggers when your base level matches <condition> <level>.
- Multiple lines are treated as AND conditions.
- job <condition> <level>
- Triggers when your job level matches <condition> <level>.
- Multiple lines are treated as AND conditions.
- class <job>
- Triggers when your job is <job>
- spell [party] <spell> [, ...]
- Triggers when someone casts <spell> on you or you are in its scope.
- Party support syntax is included (optional). Also trigger on party member (as a target) by other party or monster. Ex: "spell party Lord of Vermilion"
- Comma-separated arguments are treated as OR conditions.
- Set variables:
- $.caster - returns the actor (by player/monster) which triggered the last spell syntax on you/party member/in range spell.
- $.casterName - returns the name of player/monster which triggered the last spell syntax on you/party member/in range spell.
- $.casterID - returns the ID of player/monster which triggered the last spell syntax on you/party member/in range spell.
- $.casterPos - returns the last position of player/monster which triggered the last spell syntax on you/party member/in range spell (x y).
- $.casterSkill - returns the skill name which triggered the last spell syntax on you/party member/in range spell.
- $.casterTarget - returns the "location of spell" which triggered the last spell syntax on you/party member/in range spell.
- $.casterTargetName - returns the name of the party member that is in the range of the triggered (as a target) last spell syntax.
- $.casterDist - returns the distance (between the caster and YOU) which triggered the last spell syntax on you/party member/in range sp
- monster [not] <monster(s) name> <condition> [<distance>]
- Triggers when <monster(s) name> is near. If <distance> is not set, it will consider the value from clientSight.
- Comma-separated arguments are treated as OR conditions.
- Multiple lines are treated as AND conditions.
- Set variables:
- $.lastMonster - name of the last monster that triggered the automacro.
- $.lastMonsterPos - triggered monster position. Ex: x, y map_name
- $.lastMonsterDist - distance between the triggered monster and you.
- $.lastMonsterID - the ID of the triggered monster.
- $.lastMonsterCount - risk point (available only for monster syntax)
- aggressives <condition> <number>
- Triggers at <number> of aggressives.
- Multiple lines are treated as AND conditions.
- player ("<player name>" | /<regexp>/[i]) [, <distance> ]
- Triggers when <player name> is on screen and not more than <distance> blocks away.
- Multiple lines are treated as AND conditions.
- equipped [<slot>] (<item> | none) [, ...]
- Triggers when <item> or none is equipped [in slot <slot>]
- Slots are topHead, midHead, lowHead, leftHand, rightHand, robe, armor, shoes, leftAccessory, rightAccessory and arrow.
- Comma-separated arguments are treated as OR conditions.
- Multiple lines are treated as AND conditions.
- var <variable> (unset | <condition> <value>)
- Triggers when <variable> is either unset or matches <condition> <value>.
- Multiple lines are treated as AND conditions.
- varvar <nested variable> (unset | <condition> <value>)
- Triggers when <nested variable> is either unset or matches <condition> <value>.
- Multiple lines are treated as AND conditions.
- console ("<text>" | /<regexp>/[i])
- Triggers when <text> is received on console or the text received matches <regexp>.
- The i switch means the regexp is case-insensitive.
- Set variables:
- $.lastLogMsg - the console text that trigerred the automacro.
- $.lastMatchN - backreference from regexp.
- pm ("<text>" | /<regexp>/[i]) [, <player>]
- Triggers when <text> is received by PM [from <player>] or the text received matches <regexp>.
- The i switch means the regexp is case-insensitive.
- Set variables:
- $.lastpm - the name of the player who PMed you
- $.lastpmMsg - the message
- pubm ("<text>" | /<regexp>/[i]) [, <distance>]
- Triggers when a public message [within a distance of <distance>] is received and it is <text> or matches <regexp>
- The i switch means the regexp is case-insensitive.
- Set variables:
- $.lastpub - player's name
- $.lastpubMsg - player's message
- party ("<text>" | /<regexp>/[i])
- Triggers when <text> is received by party chat or the text received matches <regexp>.
- The i switch means the regexp is case-insensitive.
- Set variables:
- $.lastparty - player's name
- $.lastpartyMsg - player's message
- guild ("<text>" | /<regexp>/[i])
- Triggers when <text> is received by guild chat or the text received matches <regexp>.
- The i switch means the regexp is case-insensitive.
- Set variables:
- $.lastguild - player's name
- $.lastguildMsg - player's message
- playerguild (<guild list> [, ...] | <guild.txt>) [, <distance>]
- Trigers when guild list (guild1, guild2, ..., guildN) or lists of guilds inside control/guild.txt matches player's guild name when charNameUpdate or player hook-on-demand packets is received. Further discussion could be found at Forums.
- If <distance> is not defined, clientSight value will be considered.
- Comma-separated guild list are treated as OR conditions.
- Set variables:
- $.lastPlayerID - return the account ID of the player that trigger the syntax
- $.lastGuildName - return the guild name of the player that trigger the syntax
- $.lastGuildNameBinID - return the ID of the player that trigger the syntax
- $.lastGuildNameBinIDDist - return the distance(from you) of the player that trigger the syntax
- $.lastGuildNameBinIDName - return the player's name that trigger the syntax
- $.lastGuildNameBinIDJobName - return the job class of the player that trigger the syntax
- hook <hookname>
- Triggers when openkore calls <hookname>.
- save <hash key> (use in combination with hook)
- Saves the value of <hash key> in a variable $.hooksaveN.
automacro hook { hook packet_privMsg save MsgUser save Msg call { log Player $.hooksave1 said $.hooksave2 } }
- whenGround [not] <spell>
- Triggers when we are in the effect of ground status.
- Comma-separated list will be treated as OR condition
- areaSpell <spell> [<distance>]
- Triggers when someone uses an area of spell (centre) that is in the scope of the distance condition from you. If <distance> is not defined, it will consider clientSight value.
- Comma-separated arguments are treated as OR conditions.
- localtime <condition> <time>
- Triggers when CPU clock time matches the given <condition> <time>.
- Time is on 24h format. Ex: 11:22:33 (hour:minute:second)
- Multiple lines are treated as AND conditions.
- run-once (0 | 1)
- When set to 1 the automacro will be locked after being triggered.
- Use the macro command release to unlock this automacro.
- overrideAI (0 | 1)
- When set to 1, the macro ignores openkore's AI. This means it won't pause upon "move" or "status dead".
- delay <n>
- Waits for <n> seconds before calling the corresponding macro.
- timeout <n>
- Waits at least for <n> seconds before this automacro can be triggered again.
- macro_delay <n>
- Overrides the global macro delay setting for the called macro.
- priority <num>
- Chooses which automacros should be checked before others. The smaller the <num> is, the sooner the automacro gets checked. If priority is not given, the priority is assumed to be 0. (zero: check first).
- exclusive (0 | 1)
- Automacros which have exclusive set cannot be interrupted by other automacros.
- set <variable> <value>
- Sets variable <variable> to <value>. You can have multiple set lines per automacro.
- orphan <method>
- Sets the method of how to deal with orphaned macros.
Example
automacro sp { location prontera run-once 1 call { log i'm on prontera o/ } }
Always remember, when opening a {, always close it with a }.
Orphaned Macros
It may happen - for example by using ai clear while a macro is running - that a macro becomes orphaned. That means the macro object exists but cannot continue because it requires the AI queue to contain the entry "macro" (or "deal") at the first place. When the AI queue gets cleared, the "macro" entry vanishes. There are three methods:
terminate | terminates the macro (equivalent to macro stop) |
reregister | re-registers to AI queue, overriding other entries. This means to force the continuation of the macro. |
reregister_safe | re-registers to AI queue when AI gets idle. This means the macro will continue when all other tasks are done. |
Perl Subroutines
Macro plugin support Perl subroutines in macros. You can now create any simple Perl function without limitations from the eval command.
Example No.1 - how to create a Perl Subroutine function in Macro
macro sub { $list = Orange, Milk, Soya, Peach if (existsInList("$list", "PeAch")) goto ok log Not Match!!!; stop :ok log Match!!! $x = @eval(existsInList("$list", "PeAch")) log \$x = $x # $x here is 1 } sub existsInList { my ($list, $val) = @_; return 0 if ($val eq ""); my @array = split / *, */, $list; $val = lc($val); foreach (@array) { s/^\s+//; s/\s+$//; s/\s+/ /g; next if ($_ eq ""); return 1 if (lc($_) eq $val); } return 0; }
Example No.2 - how to create a re-writable file function using Perl Subroutine in Macro
automacro confHP1 { hp > 85% exclusive 1 run-once 1 set setting Demon Pungus #becareful on your case, its case sensitive set attack 1 set teleport 0 set telesearch 1 call HP } automacro confHP2 { hp < 75% exclusive 1 run-once 1 set setting Demon Pungus set attack 1 set teleport 2 set telesearch 1 call HP } macro HP { #Getting the value of the $setting monster name Ex: $setting $exist1 $exist2 $exist3 $exist1 = @eval (defined Misc::mon_control("$setting")?Misc::mon_control("$setting")->{attack_auto}:"None") $exist2 = @eval (defined Misc::mon_control("$setting")?Misc::mon_control("$setting")->{teleport_auto}:"None") $exist3 = @eval (defined Misc::mon_control("$setting")?Misc::mon_control("$setting")->{teleport_search}:"None") log Old Values are $setting $exist1 $exist2 $exist3 log Changing the values to $setting $attack $teleport $telesearch do eval Misc::mon_control("$::Macro::Data::varStack{setting}")->{attack_auto} = $attack; Misc::mon_control("$::Macro::Data::varStack{setting}")->{teleport_auto} = $teleport; Misc::mon_control("$::Macro::Data::varStack{setting}")->{teleport_search} = $telesearch log Writting mon_control.txt with new values rewrite() # see the sub-routine function below log Reloading mon_control.txt do reload mon_control $exist1 = @eval (defined Misc::mon_control("$setting")?Misc::mon_control("$setting")->{attack_auto}:"None") $exist2 = @eval (defined Misc::mon_control("$setting")?Misc::mon_control("$setting")->{teleport_auto}:"None") $exist3 = @eval (defined Misc::mon_control("$setting")?Misc::mon_control("$setting")->{teleport_search}:"None") log New mon_control.txt Setting: $setting $exist1 $exist2 $exist3 log Macro done #if $teleport = 0 ; means the Higher automacro HP is currently triggered #if $teleport = 2 ; means the Lower automacro HP is currently triggered if ($teleport < 2) goto releaseHighHp :releaseLowHp release confHP1 stop :releaseHighHp release confHP2 stop } sub rewrite { my $monster = Misc::mon_control("$::Macro::Data::varStack{setting}"); my @lines = (); if (open(FILE, "<:utf8", Settings::getControlFilename("mon_control.txt"))) { while (<FILE>) { $_ =~ s/\x{FEFF}//g; chomp($_); if ($_ =~ /^#/ || $_ =~ /^\n/ || $_ =~ /^\r/) { push @lines,$_; next } $_ =~ /^(\d+|([a-zA-Z' ]+)*) -?\d/; if ("$::Macro::Data::varStack{setting}" eq $1 && defined $monster) { $_ = $1; $_ =~ s/\s+$//; push @lines,"$_" . " $monster->{attack_auto} $monster->{teleport_auto} $monster->{teleport_search} $monster->{attack_lvl} $monster->{attack_jlvl} $monster->{attack_hp} $monster->{attack_sp} $monster->{weight}" } else {push @lines,$_} } close FILE } open(FILE, ">:utf8", Settings::getControlFilename("mon_control.txt")); print FILE join "\n", @lines; close FILE; }
Comments
The macro files allow comments, i.e. lines that are ignored by the macro plugin.
- Lines starting with a # will be treated as a comment.
- Everything after a space and followed by a # will also be ignored.
macro happy { # this is a comment line log I'm Happy # this is also a comment }
Will print:
[log] I'm Happy
Examples with Explanations
I assume you already know how to use Console Commands and understand how they work. If not, before going further, read through all Console Commands and try out ones like a, ai, move, cart get, storage add, talk, deal, take, direction commands, sl, sm, relog, pm and others.
Keep another page with this manual open for cross reference.
Okay, so there are 2 types of macros
- automacros – these trigger automatically
- macros – these do not trigger automatically but need to be called manually or by an automacro
Automacros
Automacros are macros which automatically trigger when certain conditions are met, just like how blocks in config.txt trigger depending on the conditions set in them.
The point of automacros is that you use them to check for conditions. When the condition is fulfilled, you can either respond to it in the automacro or call a macro to do it. The format for automacro is...
automacro <name> { condition 1 condition 2 …... …... call { command 1 command 2 ….. ….. } timeout <n seconds> #(if necessary) }
For example, suppose you're playing manually but your slave priest is on Kore, and you want it to warn you if it's running out of sp, you can use an automacro like this....
automacro sp { sp < 200 call { do c sp low } timeout 10 }
Taking it line by line,
- automacro sp { - you need to put automacro to tell kore that its an automacro. Then you put the name of the macro, in this case its “sp”. Then you need to put an opening bracket “{“ which tells Kore that the automacro's code begins there.
- sp < 200 – After the “{“, you put the conditions on successive lines. Here, there is only one condition and I think its clear that the condition is that sp should be below 200.
- call { – The word “call” tells Kore that now you're going to be putting commands, not conditions. The opening bracket “{“ tells Kore that the commands will start now. These commands are the ones that will get carried out when the conditions are met, here when sp goes below 200.
- do c sp low – “do” tells Kore that this is a command, something to be done. After “do”, just leave a space and type in the console command you want to execute exactly the way you do in the Kore console.
- } – This closing bracket “}” tells Kore that the commands have ended.
- timeout 10 – This isn't a condition or a command, it works the same way it works in normal Kore blocks, so this automacro cannot trigger within 10 seconds of it already having been triggered. I ALWAYS put timeouts, so even if my conditions are faulty, the automacro doesn't spam and mess up whatever my bot is doing. Otherwise if your automacro is messed up then you could die or something, so its better to put an appropriate timeout.
- } – This closing bracket “}” tells Kore that your automacro code has ended.
So basically whenever, the bot's sp goes below 200, it says in public chat “sp low”. This also has the advantage of making your bot not look like a bot =p.
Here's another macro which illustrates how you can use macros to handle weird situations which Kore is not equipped to deal with. When fighting against metalings, they often strip you and then your oh-so-smart bot punches! To get around this, put the weapon you use in default auto equip and use this macro.
automacro strip { status Strip Weapon call { do tele do relog 10 } timeout 10 }
Taking it line by line....
- automacro strip { - Tell Kore this is an automacro, and it's name is "strip". The '{' tells Kore the code of the automacro starts here.
- status Strip Weapon - The only condition in this macro. This checks your list of statuses for the status "Strip Weapon". Thus, when you are stripped by a Metaling, you get the "Strip Weapon" status and this condition will be fulfilled.
- call { - The word "call" and "{" tells Kore that the commands to be executed start after the '{'
- do tele - "do" tells Kore that what comes after is a console command to be carried out. Here, the command is "tele" so you teleport away from the Metaling, so that in case you lag or something, you aren't killed while executing the next instruction which is.....
- do relog 10 - Tells Kore to relogin in 10 seconds, because when you login again, your "strip weapon" status is cleared.
- } - The closing bracket '}' tells Kore the commands have ended.
- timeout 10 - Ensures automacro is not spammed, and 10 seconds is enough time to execute the automacro. So after 10 seconds, if for some reason you are still stripped, this automacro will trigger again. However, if you re-login and are stripped within 10 seconds, then macro will not trigger again untill the 10 seconds are up.
- } - The closing bracket '}' tells Kore the macro code has ended.
Summarising, on being stripped, you teleport away from the monster and then relogin, with a timeout of 10 seconds to ensure that the automacro is not spammed. Since the weapon you're using is filled in the default weapon option, after re-logging in, Kore will automatically re-equip that weapon.
Let's try a more complicated macro. If you have a priest, you would want it to warp back to its lockmap or the nearest warp-able map near its lockmap. This macro does it. From the savemap, the bot takes the same route to the lockmap each time. So in the first map outside the town, just set it to move to a designated tile, and cast warp on a nearby tile, and then move to that tile. You will need delays to allow the spell to be cast and commands to be completed.
automacro warp { map gef_fild07 inventory "Blue Gemstone" > 0 call { do ai manual pause 1 do move 319 187 do sl 27 316 188 pause 2 do warp 1 pause 1 do move 316 188 do ai on } timeout 20 }
Taking it line by line,
- automacro warp { - As explained, the automacro's name is warp, and “{“ indicates that the automacro begins.
- map get_fild07 - The first condition, the automacro will only trigger if the map is gef_fild07.
- inventory “Blue Gemstone” > 0 - Second condition, ensures there is atleast one blue gemstone in the inventory so that warp portal can be cast. Obviously you need a getAuto in config.txt for the gemstones.
- call { - Tells Kore that the commands start here.
- do ai manual - Frequently, I use this command in the more complicated and longer macros, so that Kore doesn't get diverted into doing something else while your macro is running, for example, attacking a monster or gathering up an item. In this case I'm using it so that the bot doesn't continue walking.
- pause 1 - Inserts a delay of 1 second before the next command is carried out, VERY IMPORTANT. If you don't use delays then Kore can and will miss steps in the macro and the result is a mess.
- do move 319 187 - The “move” console command is used to move your bot to a set location.
- do sl 27 316 188 - The “sl” console command is used to make your priest cast warp portal on a convenient spot near your location, in this case (316,188).
- pause 2 - Very Important. A delay of 2 seconds is put, allowing enough time to cast warp portal. If you priest has low dex, this delay should be increased.
- do warp 1 - Console command “warp” is used to select memo location 1.
- pause 1 - 1 second delay to allow the portal to form.
- do move 316 188 - Move to the portal and Voila! You have been warped to the map.
- do ai on - You set ai to manual at the beginning of this macro, so now you need to turn it back on.
- } - Closing bracket indicates end of commands.
- timeout 20 - Ensures that the bot does not spam the automacro. The timeout should be large enough to allow the completion of the automacro, so that the automacro does not trigger again while it is in execution.
- } - Closing bracket indicates end of automacro code.
Note the use of appropriate delays and timeouts in this automacro.
The macro plugin also has many useful built-in variables which give you your position for example. It's all listed in the macro manual. I just want to show how to extract your position from these variables.
$.pos gives you your position. Now to get your x and y coordinates the code is,
$px = @arg ("$.pos", 1) $py = @arg ("$.pos", 2)
Here, the x coordinate is the 1st value in $.pos so we have a '1'. Similarly, the y coordinate is the second value in $.pos so we have a '2'.
If you have a “monster” condition in your automacro, $.lastmonsterpos gives the position of that monster. To extract the x and y coordinates the code is,
$mx = @arg ("$.lastMonsterPos", 1) $my = @arg ("$.lastMonsterPos", 2)
"run-once"
Frequently, the run-once condition is used instead of a timeout. It allows the automacro to run only once so that the automacro isn't spammed. To get the automacro to run again, a release command needs to be executed. However, due to a rogue situation that the macro hangs and the release macro isn't executed, your automacro is effectively stuck. To get around this, use a timeout instead of using run-once.
The normal macros
In the 3 examples given, everything was done using automacros. So you're probably wondering what the point of macros is if everything can be done using automacros. Well, not everything can be done using automacros. For example, it is not possible to use macro variables such as $.pos in an automacro. So, if you get errors like “not an automacro variable”, it means that it cannot be done in an automacro but has to be done using a macro. In such a case, the automacro needs to call a macro.
Regular Expressions
Sometimes, in a macro, you need to compare, say the names of characters near you to see if it matches a certain name. This is where regular expressions come in handy. If you're new to macros, you can read this later as it can be a bit complicated, the more advanced regexps can look hellish =P Visit http://www.regular-expressions.info/quickstart.html where it's explained fairly well. I'm just going to put down some basics here.
$.lastpubMsg = /(A|a)uto (S|s)torage/
Here, $.lastpubMsg is your macro variable holding the last public chat message. A regular expression can just be plain text so it could have been /auto storage/ or /auto/ and Kore would have checked if the public chat contained "auto storage" or "auto".
However, here we have used the "|" symbol which means "or". Notice 'A' and 'a' are contained in brackets with a '|' between them. It means both 'auto' and 'Auto' are checked for. Similarly, both 'storage' and 'Storage' are checked for.
Now suppose you want to check for repetition, say 'aauto storage' also, then you may use:
/(a+|A+)uto (S|s)torage/
Notice I've used a '+'. This tells Kore that the character it is directly after, in this instance 'a' or 'A', should be present one or more times. So even if someone says "aaaaaaaaaauto storage', it will be valid. Other checks like the '+' are:
- * matches 0 or more times e.g. /(a*|A*)uto Storage/ so "uto storage" will also work.
- + matches 1 or more times e.g. as above.
- ? matches 1 or 0 times e.g. /(a?|A?)uto Storage/ so "uto storage" and "auto storage" work but "aaaauto storage" won't.
So if you want to check for "Kobold" just do /Kobold/ and if "Kobold" is anywhere in the string, it will be valid. For Kobold-1 and Kobold-2 only it will be /Kobold-(1|2)/.
Regexps may also come in handy when you're using the "console /<regexp>/" condition in automacros, if you need to check for a variety of trigger texts.
These are just the basics. I recommend referring to the link provided above if you need to make a more complicated regexp.
How to write a macro
Now that you have some idea of what a macro is, try writing one
- Figure out under exactly what conditions you want your automacro to trigger
- Logically think out the steps your bot needs to perform in the automacro. Go step by step over this carefully.
- Ensure you have inserted appropriate pauses between the steps.
- Ensure you have a timeout or a run-once in your macro to prevent spamming of it.
- Now put the code in macros.txt and start the bot or reload macros.txt. If all is fine you won't get any error messages. But if there is a problem in the syntax, say you missed out a “}”, then you will get an error message and the macro won't work. Figure out what the error is, correct it, and reload macros.txt again to check if you corrected it properly or not.
FAQ
- I have an automacro that checks for the amount of an item in my inventory / cart to be less than a given value or equal to zero (e.g. inventory "red potion" <= 30) but that automacro triggers also on map change. Why is that so and what should I do?
- When you're changing the map all items vanish from your inventory for a short time. That happens with the official client, too. To avoid this, add an additional check for an item that you always carry with you, like inventory "Jellopy" > 0
- I get disconnected from map server when running a macro!
- The commands are sent too fast. Increase macro_delay or add pause lines between your do commands
- I'm getting Malformed UTF-8 character (fatal), what is this?
- This error happens when your macros.txt is not saved in UTF-8 encoding.
- To solve it, open your macros.txt and if you're using Notepad, when you are going to save, change Encoding to UTF-8. (If that does not help - do not use Notepad.)
- If you're using Notepad++ or other text editor, go to Format > UTF-8 (without BOM) and save.
Author
The macro plugin was written by arachno. Special thanks to ezza who is updating the macro plugin now.