Difference between revisions of "macro plugin"

From OpenKore Wiki
Jump to navigation Jump to search
(temp)
 
Line 1: Line 1:
[http://web.archive.org/web/20080201014333/www.openkore.com/wiki/index.php/Macro_plugin Macro_plugin 10.02.2008]
+
With this plugin you can predefine command sequences (macros) which are run either manually or by situation-dependent triggers. The latest version is 2.0.3.
  
[http://u1leo.com/macro/Macro_plugin.htm http://u1leo.com/macro/Macro_plugin.htm]
+
== Instalation ==
 +
* Download your macro plugin. You can get it [http://bibian.ath.cx/?file=macro.tar.gz here] or from [[SVN]].
 +
* Go to your OpenKore main folder (the folder which contains the file openkore.pl) and create a subfolder called plugins, if there isn't already one.
 +
* Inside the Macro plugin's zipfile, you will find the file macro.pl and the folder Macro. Extract them to your plugins folder.
 +
* In your OpenKore control folder, create a blank file named macros.txt. In this file you will put your macros/automacros.
 +
 
 +
After installation, your OpenKore file tree should look like this (ignoring openkore's own files):
 +
openkore
 +
|-- openkore.pl
 +
|-- control
 +
|  |-- macros.txt
 +
|-- fields
 +
|-- logs
 +
|-- plugins
 +
|  |-- Macro
 +
|  |  |-- Automacro.pm
 +
|  |  |-- Data.pm
 +
|  |  |-- Parser.pm
 +
|  |  |-- Script.pm
 +
|  |  |-- Utilities.pm
 +
|  |-- macro.pl
 +
|-- src
 +
|-- tables
 +
 
 +
 
 +
== Commands ==
 +
=== Syntax ===
 +
macro <macroname> [options] [-- parameter(s)]
 +
 
 +
Runs macro <macroname>.
 +
 
 +
{| class="wikitable" border="1" cellspacing="0"
 +
|-style=background-color:#F9F9F9;
 +
! Option
 +
! Value
 +
! Description
 +
|-
 +
|align=center| -repeat
 +
|align=center| n
 +
|align=center| repeat the macro '''n''' times
 +
|-
 +
|align=center| -overrideAI
 +
|align=center| none
 +
|align=center| override openkore's AI
 +
|-
 +
|align=center| -macro_delay
 +
|align=center| delay
 +
|align=center| override global macro_delay for this macro
 +
|-
 +
|align=center| -exclusive
 +
|align=center| none
 +
|align=center| do not allow automacros to cancel this macro
 +
|-
 +
|align=center| -orphan
 +
|align=center| method
 +
|align=center| use method for handling orphaned macros
 +
|}
 +
 
 +
 
 +
Parameters for the macro can be specified after a double dash (--). These parameters are saved to the variables $.param1 to $.paramN. Example:
 +
 
 +
macro foo {
 +
  log Parameter 1 is $.param1
 +
  log Parameter 2 is $.param2
 +
}
 +
 
 +
 
 +
When called as '''''macro foo -- foo bar''''' it would print out
 +
 
 +
[macro] Parameter 1 is foo
 +
[macro] Parameter 2 is bar
 +
 
 +
 
 +
; macro list
 +
: Lists all available macros.
 +
 
 +
; macro stop
 +
: Stop current macro.
 +
 
 +
; macro pause
 +
: Interrupts the running macro.
 +
 
 +
; macro resume
 +
: Resumes an interrupted macro.
 +
 
 +
; macro version
 +
: Print version number.
 +
 
 +
; macro reset [<name(s)>]
 +
: Resets all run-once automacros or the specified automacro <name>.
 +
 
 +
; macro status
 +
: Shows whether or not a macro is currently running. If that's the case it shows the delay for the next command, the current line, overrideAI setting, whether or not it has finished and whether or not the macro registered to AI queue.
 +
 
 +
 
 +
== Configuration files ==
 +
 
 +
; control/macros.txt
 +
: Put your macros and automacros in here. You can change the file's name depending on what you configured on config ''macro_file''.
 +
 
 +
; control/timeouts.txt
 +
: Add '''''macro_delay''''' and set it to the number of seconds you want the plugin to pause between commands.
 +
 
 +
; control/config.txt
 +
{| class="wikitable" border="1" cellspacing="0"
 +
|-style=background-color:#F9F9F9;
 +
!Option
 +
! Value
 +
!Description
 +
|-
 +
|align=center| macro_nowarn
 +
|align=center| 0 <br/> 1
 +
|align=center| enable or disable the annoying warnings when not using call in your automacro(s)
 +
|-
 +
|align=center| macro_orphans
 +
|align=center| terminate <br/> reregister <br/> reregister_safe
 +
|align=center| override openkore's AI
 +
|-
 +
|align=center| macro_file
 +
|align=center| file name
 +
|align=center| file containing the macros ("macros.txt" by default)
 +
|-
 +
|align=center| macro_allowDebug
 +
|align=center| 0 <br/> 1
 +
|align=center| console-check also processes openkore's debug messages (default: 0). Warning: slows down the plugin.
 +
|}
 +
 
 +
 
 +
== Macro Syntax ==
 +
macro MacroName {
 +
    do this..
 +
    and that..
 +
    yattayatta..
 +
}
 +
 
 +
 
 +
You can use any name you want for your macro. Becareful to not make two macros with the same name.
 +
All the [[Console Commands]] can be used in macros.
 +
 
 +
; do <command>
 +
: Run <command>. Commands from [[Console Commands]].
 +
 
 +
macro foo {
 +
    do move 123 234 prontera
 +
    do sit
 +
    do c hello world
 +
}
 +
 
 +
 
 +
; log <text>
 +
: Prints a text in the console.
 +
 
 +
macro foo {
 +
  log This line logs a text to console.
 +
  log All your base are belong to us!
 +
}
 +
 
 +
 
 +
; pause [<n>]
 +
: Pauses the macro for '''n''' seconds.
 +
 
 +
macro foo {
 +
    log It's 10:00:00
 +
    pause 10
 +
    log Not it's 10:00:10
 +
    log 10 seconds have passes after the first print.
 +
}
 +
 
 +
 
 +
; call <macroname> [<n>]
 +
: Calls macro <macroname> [<n> times]. When <macroname> is finished the current macro continues.
 +
 
 +
; release (<name> | all)
 +
: Reenables a locked automacro ("run-once" keyword or locked by "lock") or reenables all automacros when using release all.
 +
 
 +
; lock (<name> | all)
 +
: Locks an automacro and disables it's checks. To locks all automacros, use ''lock all''.
 +
 
 +
; stop
 +
: Immediately terminates the running macro.
 +
 
 +
; set <option> <value>
 +
: Sets macro features:
 +
:* orphan method
 +
:* macro_delay timeou
 +
:* overrideAI [0|1]
 +
:* repeat times
 +
:* exclusive [0|1]
 +
 
 +
 
 +
=== Variable declaration and usage ===
 +
You can define and work with own variables.
 +
To set a variable use ''$variable = value'', to recall the value use ''$variable''.
 +
 
 +
macro Hello {
 +
    $var = Hello
 +
    $var2 = Word!
 +
    log $var $var1
 +
}
 +
 
 +
This would print in the console:
 +
 
 +
[log] Hello Word!
 +
 
 +
If you want to use the '''''$''''' symbol you should escape it with '''''\'''''.
 +
 
 +
macro money {
 +
    log I have a lot of \$
 +
}
 +
 
 +
 
 +
It is possible to increment and to decrement a variable using ''$variable++'' or ''$variable--''.
 +
 
 +
macro Counter {
 +
    $counter = 0
 +
    log Counter is at $counter
 +
    $counter++
 +
    log Not it's $counter
 +
    $counter--
 +
    log It's back to $counter
 +
}
 +
 
 +
The result is:
 +
log Counter is at 0
 +
log Now it's 1
 +
log It's back to 0
 +
 
 +
 
 +
For calculation use ''''' @eval '''''.
 +
 
 +
macro math {
 +
    $num = 2
 +
    $num2 = 3
 +
    $result = @eval($num+$num2)
 +
    log $num + $num2 = $result
 +
}
 +
 
 +
The result is:
 +
log 2 + 3 = 5
 +
 
 +
You can also use @eval inside @eval
 +
 
 +
macro math {
 +
    $num = 2
 +
    $num2 = 3
 +
    $result = @eval(@eval($num+$num2) - @eval($num+$num2))
 +
    log ($num + $num2) - ($num + $num2) = $result
 +
}
 +
 
 +
{| class="wikitable" border="1" cellspacing="0"
 +
|-style=background-color:#F9F9F9;
 +
! Operator
 +
! Description
 +
|-
 +
|align=center| +
 +
|align=center| Plus
 +
|-
 +
|align=center| -
 +
|align=center| Minus
 +
|-
 +
|align=center| *
 +
|align=center| Times
 +
|-
 +
|align=center| /
 +
|align=center| Divided
 +
|}
 +
 
 +
 
 +
You can extract the first element from a comma-separated list using like this:
 +
 
 +
macro foo {
 +
  $list = banana, apple, strawberry, grape
 +
  $var = [$list]
 +
  log The first element of \$list is $var
 +
  log Now \$list contains $list
 +
}
 +
 
 +
The result it:
 +
log The first element from \$list is Banana
 +
log \$list contains apple, strawberry, grape
 +
 
 +
 
 +
'''''Note.''''' Variable names can only contain letters and numbers,.
 +
 
 +
 
 +
== Nested Variables ==
 +
You can define dynamic or nested variables.
 +
 
 +
macro foo {
 +
    $name = Camila
 +
    ${$name} = Brazil
 +
    log $name lives on ${$name}
 +
}
 +
 
 +
The result is:
 +
 
 +
log Camila lives on Brazil
 +
 
 +
 
 +
== Special Variables ==
 +
There are special readonly variables which begin with a dot. They are pre-defined with the macro plugin.
 +
 
 +
:* $.map - the map you're on ("prontera")
 +
:* $.pos - your current position ("123 234")
 +
:* $.time - current time as unix timestamp ("1131116304")
 +
:* $.datetime - current date and time ("Fri Nov 4 15:59:36 2005")
 +
:* $.hp - current hp
 +
:* $.sp - current sp
 +
:* $.lvl - current base level
 +
:* $.joblvl - current job level
 +
:* $.spirits - current number of spirit spheres
 +
:* $.zeny - current amount of zeny
 +
:* $.status - current statuses in a comma-separated list
 +
:* $.paramN - command line parameters (see commands)
 +
:* $.caller - name of the last triggered automacro
 +
:* $.weight - return the current weight of the character
 +
:* $.maxweight - return the maximum weight of the character
 +
 
 +
 
 +
== Special Keywords ==
 +
They are used to return values depending on the parameters given.
 +
 
 +
; @npc (<x> <y> | /regexp/i | "<name>")
 +
: Return NPC's ID which location is <x> <y> or NPC's name match regexp is equal to <name> . If no NPC is found returns -1.
 +
 
 +
; @inventory (<item>)
 +
: Returns Inventory Item ID of <item>. If <item> doens't exist returns -1.
 +
 
 +
; @Inventory (<item>)
 +
: Same as @inventory but returns all matching IDs as a comma-separated list or -1 if the item was not found
 +
 
 +
; @invamount (<item>)
 +
: Returns the amount of the given <item> in inventory.
 +
 
 +
; @cart (<item>)
 +
: Returns Cart Item ID of <item>. If <item> doesn't exist returns -1.
 +
 
 +
; @Cart (<item>)
 +
: Same as @cart but returns all matching IDs as a comma-separated list or -1 if the item was not found.
 +
 
 +
;@cartamount (<item>)
 +
: Returns the amount of the given <item> in cart.
 +
 
 +
; @storage (<item>)
 +
: Returns Storage Item ID of <item>. If <item> doesn't exit returns -1.
 +
 
 +
; @Storage (<item>)
 +
: Same as @storage but returns all matching IDs as a comma-separated list or -1 if the item was not found.
 +
 
 +
; @storamount (<item>)
 +
: Returns the amount of the given <item> in storage
 +
 
 +
; @player (<name>)
 +
: Returns player ID of player <name>. If player <name> is not found, returns -1.
 +
 
 +
; @vender (<name>)
 +
: Returns Vender ID of vender <name>. If vender <name> is not found, returns -1.
 +
 
 +
; @store (<name>)
 +
: Looks for an item in a store and returns ID or -1 if the item was not found.
 +
 
 +
; @shopamount (<item>)
 +
: Returns the amount of the given <item> in shop.
 +
 
 +
; @random ("<argument1>", "<argument2>"....)
 +
: Returns randomly one of the given arguments .
 +
 
 +
; @rand (<n>, <m>)
 +
: Returns a random number between (and including) <n> and <m>.
 +
 
 +
; @eval (<argument>)
 +
: Evaluates the given <argument>.
 +
 
 +
; @arg ("<argument>", <n>)
 +
: Returns the <n>th word of <argument> or an empty string if the word index is out of range.
 +
'''''Note.''''' <n> can also be a variable.
 +
 
 +
; @config (<variable>)
 +
: Returns the value of <variable> specified in config.txt.
 +
 
 +
; @venderitem (<name>)
 +
: Looks for an item in a players shop and returns ID or -1 if the item was not found.
 +
 
 +
; @venderprice (<indexID>)
 +
: Looks for an item in a players shop and returns its price.
 +
 
 +
; @nick (<word>)
 +
: Escape all the regexp characters with '''\'''.
 +
 
 +
 
 +
== Chaining commands ==
 +
You can run multiple commands one after another without having to wait for openkore's ai or macro_delay or whatever. Just enclose these commands with '''[''' and ''']'''. 
 +
 
 +
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 }
 +
 
 +
Line 3 starts the chaining mode. This line has no delay. Lines 4, 5 and 6 are run as soon as the previous command has finished with no delay and they cannot be interrupted. Line 7 stops the chaining mode and line 8 will be run $macro_delay seconds after that.
 +
 
 +
 
 +
== Sub-lines ==
 +
Instanted of using one command/var assigments per line, you can separate them using ''';'''.
 +
 
 +
macro foo {
 +
    $i = 1;pause 5; log \$i = $i;$ii = 2 ; $iii = 3; $i++; $ii--; lock automacroName; release automacroName; set overrideAI 1
 +
}
 +
 
 +
Commands separated by ''';''' will have no delay between them, just like the Chaining commands, unless on commands '''pause and log'''.
 +
 
 +
 
 +
== Conditions ==
 +
Supported conditions in macro plugin are:
 +
 
 +
{| class="wikitable" border="1" cellspacing="0"
 +
|-style=background-color:#F9F9F9;
 +
! Operator
 +
! Description
 +
|-
 +
|align=center| <
 +
|align=center| less than
 +
|-
 +
|align=center| <=
 +
|align=center| less or equal to
 +
|-
 +
|align=center| ==
 +
|align=center| equal to
 +
|-
 +
|align=center| >
 +
|align=center| greater than
 +
|-
 +
|align=center| >=
 +
|align=center| greater or equal to
 +
|-
 +
|align=center| !=
 +
|align=center| not equal to
 +
|-
 +
|align=center| ~
 +
|align=center| <left part> is element of <right part (comma-separated list)>
 +
|-
 +
|align=center| =~
 +
|align=center| Check for regexp
 +
|-
 +
|align=center| arg .. arg2
 +
|align=center| Between arg and arg2. Where arg can be a number, a % or a variable.
 +
|}
 +
 
 +
 
 +
== Flow control and labels ==
 +
While all high level programming languages have constructs like "if .. else", "while", "foreach", "for .. next", "do .. while" and function calls their common denominators are "if", "goto" and "while". That's why the macro plugin only supports these three keywords. Since there are no (visible) line numbers you'll need to use labels which can be defined by a colon followed by the name of the label.
 +
 
 +
=== If statement ===
 +
Macro if conditions is very close to the perl if statements. It accepts unlimited number of statements in just one if conditions, regexp matching (unfortunately, no backreference using parenthesis) and the use of '''&&''' for '''and''' meaning and '''||''' for '''or''' meaning.
 +
==== Syntax ====
 +
You can use a simple statement
 +
if (arg <condition> arg2) (goto <label> | call <macro> [<n>])
 +
 
 +
A statement with OR condition
 +
if (arg <condition> arg2 || arg3 <condition> arg4) (goto <label> | call <macro> <n>)
 +
 
 +
A statement with AND condition
 +
if (arg <condition> arg2 && arg3 <condition> arg4) (goto <label> | call <macro> <n>)
 +
 
 +
Or with both
 +
if (arg <condition> arg2 || arg3 <condition> arg4 && arg5 <condition> arg6) (goto <label> | call <macro> <n>)
 +
 
 +
Where ''arg'' can be a variable, a nested variable, a special keyword, @eval or letters and numbers. ''<label>'' the name of a existing label, can only contain letters and numbers , ''<macro>'' the name of a existing macro and ''<n>'' the number of times it will call the macro.
 +
Conditions can be found on [[Macro plugin#Conditions|Conditions]].
 +
 
 +
'''''Note.''''' if ''<n>'' is '''not defined''' or it's '''0''' it will call the macro once and stop, not continuing the first macro. If it's '''1''' it will run the called macro and continue the first macro. If it's bigger than '''1''' it will call the macro '''n'''' times and continue the first macro.
 +
 
 +
==== Examples ====
 +
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
 +
}
 +
 
 +
The above macro will print '''\$num is 1''' if $num == 1, '''\$num is 2''' if $num == 2, '''\$num is 3''' if $num == 3.
 +
The same macro can be written using '''call''' instanted of '''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
 +
}
 +
 
 +
 
 +
A more complicated macro
 +
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 Loop ===
 +
A while in macros means that certain commands will be ran while the defined conditions are met.
 +
==== Syntax ====
 +
while (arg <condition> arg) as <loop>
 +
    do bla bla
 +
    ...
 +
end <loop>
 +
 
 +
Where ''arg'' can be a variable, a nested variable, a special keyword, @eval or letters and numbers. And <loop> the name of the loop. You can give any name you want.
 +
Conditions can be found on [[Macro plugin#Conditions|Conditions]].
 +
 
 +
 
 +
==== Examples ====
 +
macro while {
 +
    $i = 0
 +
    while ($i < 10) as loop
 +
    log \$i = $i
 +
    $i++
 +
    end loop
 +
}
 +
 
 +
The result is
 +
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
 +
 
 +
 
 +
== Automacros ==
 +
Automacros are macro 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. 
 +
 
 +
=== Syntax ===
 +
automacro <name> {
 +
    <conditions> <values>
 +
    call <macro>
 +
}
 +
 
 +
Or you can omit the '''call <macro>'''
 +
automacro <name> {
 +
    <condition> <values>
 +
    call {
 +
          <commands>
 +
        }
 +
}
 +
 
 +
The first syntax is usefull if you want more than one automacro to call one simple macro.
 +
automacro First {
 +
    <conditions>
 +
    call print
 +
}
 +
  automacro Seconds {
 +
    <conditions>
 +
    call print
 +
}
 +
macro print {
 +
    log $.caller triggered
 +
}
 +
 
 +
=== Conditions ===
 +
An Automacro needs to have at least 1 conditions or it will loop forever. It can have as many conditions you want, also some conditions automatically sets some variables so you can use them in your macros.
 +
 
 +
; map <mapname>
 +
: Triggers when your current map is <mapname>.
 +
 
 +
; location [not] <mapname [<x1> <y1> [<x2> <y2>]] [, ...]
 +
: Triggers when you are [not] at the specified location.
 +
When neither <x1> <y1> nor <x2> <y2> are given it triggers when you are [not] on <mapname>.
 +
When <x2> <y2> are not given it triggers when you are [not] on <mapname> at (<x1>,<x2>).
 +
When both <x1> <y1> and <x2> <y2> are defined it triggers when you are on <mapname> somewhere between <x1>, <y1> (upper left) and <x2>, <y2> (lower right, where <x1> < <x2> and <y1> > <y2>
 +
Comma-separated arguments are treated as OR conditions:
 +
 
 +
location geffen, prontera 123 234
 +
 
 +
Triggers when you are either in geffen or in prontera at 123 234.
 +
 
 +
Multiple lines are treated as AND conditions:
 +
 
 +
location not geffen
 +
location not prontera
 +
 
 +
Triggers when you are neither in geffen nor in prontera.
 +
 
 +
 
 +
; mapchange (<mapname>|any) [, ...]
 +
:Triggers when changing map to <mapname>. If the argument is any then it triggers on any map change.
 +
Comma-separated arguments are treated as OR conditions.
 +
 
 +
 
 +
; hp <[[Macro plugin#Conditions|condition]]> <amount>[%]
 +
: Triggers when your hp matches the defined condition.
 +
Multiple lines are treated as AND Conditions.
 +
 
 +
 
 +
; sp <[[Macro plugin#Conditions|condition]]> <amount>[%]
 +
: Triggers when your sp matches the defined condition.
 +
Multiple lines are treated as AND conditions.
 +
 
 +
 
 +
; spirit <[[Macro plugin#Conditions|condition]]> <amount>
 +
: Triggers when your spirits match <condition> <amount>.
 +
Multiple lines are treated as AND conditions.
 +
 
 +
 
 +
; weight <[[Macro plugin#Conditions|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 <<[[Macro plugin#Conditions|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 <[[Macro plugin#Conditions|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>" <[[Macro plugin#Conditions|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>" <[[Macro plugin#Conditions|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>" <[[Macro plugin#Conditions|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>" <[[Macro plugin#Conditions|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 baselevel matches <condition> <level>.
 +
Multiple lines are treated as AND conditions.
 +
 
 +
 
 +
; job <[[Macro plugin#Conditions|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 it's 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 - Return the actor (by player/monster) which triggered the last spell syntax on you/party member/inrange spell.
 +
* $.casterName - Return the name of player/monster which triggered the last spell syntax on you/party member/inrange spell.
 +
* $.casterID - Return the ID of player/monster which triggered the last spell syntax on you/party member/inrange spell.
 +
* $.casterPos - Return the last position of player/monster which triggered the last spell syntax on you/party member/inrange spell (x y).
 +
* $.casterSkill - Return the skill name which triggered the last spell syntax on you/party member/inrange spell.
 +
* $.casterTarget - Return the "location of spell" which triggered the last spell syntax on you/party member/inrange spell.
 +
* $.casterTargetName - Return the name of the party member that is in the range of the triggered(as a target) last spell syntax.
 +
* $.casterDist - Return the distance (between the caster and YOU) which triggered the last spell syntax on you/party member/inrange sp
 +
 
 +
 
 +
; monster [not] <monster(s) name> <[[Macro plugin#Conditions|condition]]> [<distance>]
 +
: Triggers when <monster(s) name> is near. If <distance> is not set, it will consider the value from [[Config.txt#clientSight|clientSight]].
 +
 
 +
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 (Avaible only for monster syntax)
 +
 
 +
Comma-separated arguments are treated as OR conditions.
 +
Multiple lines are treated as AND conditions.
 +
 
 +
 
 +
; aggressives <[[Macro plugin#Conditions|condition]]>  <number>
 +
: Triggers at <number> of aggressives.
 +
Multiple lines are treated as AND conditions.
 +
 
 +
 
 +
; player ("<playername>" | /<regexp>/[i]) [, <distance> ]
 +
: Triggers when <playername> 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 | <[[Macro plugin#Conditions|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.
 +
 
 +
 
 +
; 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 partychat 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 guildchat 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
 +
 
 +
 
 +
; 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 use an area of spell(centre) that is in the scope of the distance condition from you. If <distance> is not defined, it will consider [[Config.txt#clientSight|clientSight]] value.
 +
Comma-separated arguments are treated as OR conditions.
 +
 
 +
 
 +
; localtime <[[Macro plugin#Conditions|condition]]> <time>
 +
: Triggers when defined the conditions for <time> mets.
 +
Time is on 24h format.
 +
 
 +
 
 +
; 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>
 +
: Wait 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>
 +
: Choose which automacros should be checked before others. The smaller <num> is 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 [[Macro plugin#Orphaned Macros|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 '''}'''.
 +
 
 +
 
 +
== 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:
 +
 
 +
{| class="wikitable" border="1" cellspacing="0"
 +
|-style=background-color:#F9F9F9;
 +
|-
 +
|align=center| terminate
 +
|align=center| terminates the macro (equivalent to macro stop)
 +
|-
 +
|align=center| reregister
 +
|align=center| re-registers to AI queue, overriding other entries. This means to force the continuation of the macro.
 +
|-
 +
|align=center| reregister_safe
 +
|align=center| 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. Uou can now use perl without all the limitations from '''eval''' command.
 +
 
 +
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;
 +
}
 +
 
 +
 
 +
== Comments ==
 +
The macro files allow comments, i.e. lines that are ignored by the macro plugin. Lines starting with a # will be treated as comment.
 +
macro happy {
 +
      # this is a comment line
 +
    log I'm Happy
 +
}
 +
 
 +
Will print:
 +
 
 +
[log] I'm Happy
 +
 
 +
 
 +
== 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 you used some special character on some of your macros. 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 you're using Notepad++, 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.

Revision as of 21:00, 7 November 2009

With this plugin you can predefine command sequences (macros) which are run either manually or by situation-dependent triggers. The latest version is 2.0.3.

Instalation

  • Download your macro plugin. You can get it here or from SVN.
  • Go to your OpenKore main folder (the folder which contains the file openkore.pl) and create a subfolder called plugins, if there isn't already one.
  • Inside the Macro plugin's zipfile, you will find the file macro.pl and the folder Macro. Extract them to your plugins folder.
  • In your OpenKore control folder, create a blank file named macros.txt. In this file you will put your macros/automacros.

After installation, your OpenKore file tree should look like this (ignoring openkore's own files):

openkore
|-- openkore.pl
|-- control
|   |-- macros.txt
|-- fields
|-- logs
|-- plugins
|   |-- Macro
|   |   |-- Automacro.pm
|   |   |-- Data.pm
|   |   |-- Parser.pm
|   |   |-- Script.pm
|   |   |-- Utilities.pm
|   |-- macro.pl
|-- src
|-- tables


Commands

Syntax

macro <macroname> [options] [-- parameter(s)]

Runs macro <macroname>.

Option Value Description
-repeat n repeat the macro n times
-overrideAI none override openkore's AI
-macro_delay delay override global macro_delay for this macro
-exclusive none do not allow automacros to cancel this macro
-orphan method use method for handling orphaned macros


Parameters for the macro can be specified after a double dash (--). These parameters are saved to the variables $.param1 to $.paramN. Example:

macro foo {
 log Parameter 1 is $.param1
 log Parameter 2 is $.param2
}


When called as macro foo -- foo bar it would print out

[macro] Parameter 1 is foo
[macro] Parameter 2 is bar


macro list
Lists all available macros.
macro stop
Stop current macro.
macro pause
Interrupts the running macro.
macro resume
Resumes an interrupted macro.
macro version
Print version number.
macro reset [<name(s)>]
Resets all run-once automacros or the specified automacro <name>.
macro status
Shows whether or not a macro is currently running. If that's the case it shows the delay for the next command, the current line, overrideAI setting, whether or not it has finished and whether or not the macro registered to AI queue.


Configuration files

control/macros.txt
Put your macros and automacros in here. You can change the file's name depending on what you configured on config macro_file.
control/timeouts.txt
Add macro_delay and set it to the number of seconds you want the plugin to pause between commands.
control/config.txt
Option Value Description
macro_nowarn 0
1
enable or disable the annoying warnings when not using call in your automacro(s)
macro_orphans terminate
reregister
reregister_safe
override openkore's AI
macro_file file name file containing the macros ("macros.txt" by default)
macro_allowDebug 0
1
console-check also processes openkore's debug messages (default: 0). Warning: slows down the plugin.


Macro Syntax

macro MacroName {
   do this..
   and that..
   yattayatta..
}


You can use any name you want for your macro. Becareful to not make two macros with the same name. All the Console Commands can be used in macros.

do <command>
Run <command>. Commands from Console Commands.
macro foo {
   do move 123 234 prontera
   do sit
   do c hello world
}


log <text>
Prints a text in the console.
macro foo {
  log This line logs a text to console.
  log All your base are belong to us!
}


pause [<n>]
Pauses the macro for n seconds.
macro foo {
   log It's 10:00:00
   pause 10
   log Not it's 10:00:10 
   log 10 seconds have passes after the first print.
}


call <macroname> [<n>]
Calls macro <macroname> [<n> times]. When <macroname> is finished the current macro continues.
release (<name> | all)
Reenables a locked automacro ("run-once" keyword or locked by "lock") or reenables all automacros when using release all.
lock (<name> | all)
Locks an automacro and disables it's checks. To locks all automacros, use lock all.
stop
Immediately terminates the running macro.
set <option> <value>
Sets macro features:
  • orphan method
  • macro_delay timeou
  • overrideAI [0|1]
  • repeat times
  • exclusive [0|1]


Variable declaration and usage

You can define and work with own variables. To set a variable use $variable = value, to recall the value use $variable.

macro Hello {
   $var = Hello
   $var2 = Word!
   log $var $var1
}

This would print in the console:

[log] Hello Word!

If you want to use the $ symbol you should escape it with \.

macro money {
   log I have a lot of \$
}


It is possible to increment and to decrement a variable using $variable++ or $variable--.

macro Counter {
    $counter = 0
    log Counter is at $counter
    $counter++
    log Not it's $counter
    $counter--
    log It's back to $counter
}

The result is:

log Counter is at 0
log Now it's 1
log It's back to 0


For calculation use @eval .

macro math {
    $num = 2
    $num2 = 3
    $result = @eval($num+$num2)
    log $num + $num2 = $result
}

The result is:

log 2 + 3 = 5

You can also use @eval inside @eval

macro math {
    $num = 2
    $num2 = 3
    $result = @eval(@eval($num+$num2) - @eval($num+$num2))
    log ($num + $num2) - ($num + $num2) = $result
}
Operator Description
+ Plus
- Minus
* Times
/ Divided


You can extract the first element from a comma-separated list using like this:

macro foo {
  $list = banana, apple, strawberry, grape
  $var = [$list]
  log The first element of \$list is $var
  log Now \$list contains $list
}

The result it:

log The first element from \$list is Banana
log \$list contains apple, strawberry, grape


Note. Variable names can only contain letters and numbers,.


Nested Variables

You can define dynamic or nested variables.

macro foo {
    $name = Camila
    ${$name} = Brazil
    log $name lives on ${$name}
}

The result is:

log Camila lives on Brazil


Special Variables

There are special readonly variables which begin with a dot. They are pre-defined with the macro plugin.

  • $.map - the map you're on ("prontera")
  • $.pos - your current position ("123 234")
  • $.time - current time as unix timestamp ("1131116304")
  • $.datetime - current date and time ("Fri Nov 4 15:59:36 2005")
  • $.hp - current hp
  • $.sp - current sp
  • $.lvl - current base level
  • $.joblvl - current job level
  • $.spirits - current number of spirit spheres
  • $.zeny - current amount of zeny
  • $.status - current statuses in a comma-separated list
  • $.paramN - command line parameters (see commands)
  • $.caller - name of the last triggered automacro
  • $.weight - return the current weight of the character
  • $.maxweight - return the maximum weight of the character


Special Keywords

They are used to return values depending on the parameters given.

@npc (<x> <y> | /regexp/i | "<name>")
Return NPC's ID which location is <x> <y> or NPC's name match regexp is equal to <name> . If no NPC is found returns -1.
@inventory (<item>)
Returns Inventory Item ID of <item>. If <item> doens't exist returns -1.
@Inventory (<item>)
Same as @inventory but returns all matching IDs as a comma-separated list or -1 if the item was not found
@invamount (<item>)
Returns the amount of the given <item> in inventory.
@cart (<item>)
Returns Cart Item ID of <item>. If <item> doesn't exist returns -1.
@Cart (<item>)
Same as @cart but returns all matching IDs as a comma-separated list or -1 if the item was not found.
@cartamount (<item>)
Returns the amount of the given <item> in cart.
@storage (<item>)
Returns Storage Item ID of <item>. If <item> doesn't exit returns -1.
@Storage (<item>)
Same as @storage but returns all matching IDs as a comma-separated list or -1 if the item was not found.
@storamount (<item>)
Returns the amount of the given <item> in storage
@player (<name>)
Returns player ID of player <name>. If player <name> is not found, returns -1.
@vender (<name>)
Returns Vender ID of vender <name>. If vender <name> is not found, returns -1.
@store (<name>)
Looks for an item in a store and returns ID or -1 if the item was not found.
@shopamount (<item>)
Returns the amount of the given <item> in shop.
@random ("<argument1>", "<argument2>"....)
Returns randomly one of the given arguments .
@rand (<n>, <m>)
Returns a random number between (and including) <n> and <m>.
@eval (<argument>)
Evaluates the given <argument>.
@arg ("<argument>", <n>)
Returns the <n>th word of <argument> or an empty string if the word index is out of range.

Note. <n> can also be a variable.

@config (<variable>)
Returns the value of <variable> specified in config.txt.
@venderitem (<name>)
Looks for an item in a players shop and returns ID or -1 if the item was not found.
@venderprice (<indexID>)
Looks for an item in a players shop and returns its price.
@nick (<word>)
Escape all the regexp characters with \.


Chaining commands

You can run multiple commands one after another without having to wait for openkore's ai or macro_delay or whatever. Just enclose these commands with [ and ].

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 }

Line 3 starts the chaining mode. This line has no delay. Lines 4, 5 and 6 are run as soon as the previous command has finished with no delay and they cannot be interrupted. Line 7 stops the chaining mode and line 8 will be run $macro_delay seconds after that.


Sub-lines

Instanted of using one command/var assigments per line, you can separate them using ;.

macro foo {
    $i = 1;pause 5; log \$i = $i;$ii = 2 ; $iii = 3; $i++; $ii--; lock automacroName; release automacroName; set overrideAI 1
}

Commands separated by ; will have no delay between them, just like the Chaining commands, unless on commands pause and log.


Conditions

Supported conditions in macro plugin are:

Operator Description
< less than
<= less or equal to
== equal to
> greater than
>= greater or equal to
!= not equal to
~ <left part> is element of <right part (comma-separated list)>
=~ Check for regexp
arg .. arg2 Between arg and arg2. Where arg can be a number, a % or a variable.


Flow control and labels

While all high level programming languages have constructs like "if .. else", "while", "foreach", "for .. next", "do .. while" and function calls their common denominators are "if", "goto" and "while". That's why the macro plugin only supports these three keywords. Since there are no (visible) line numbers you'll need to use labels which can be defined by a colon followed by the name of the label.

If statement

Macro if conditions is very close to the perl if statements. It accepts unlimited number of statements in just one if conditions, regexp matching (unfortunately, no backreference using parenthesis) and the use of && for and meaning and || for or meaning.

Syntax

You can use a simple statement

if (arg <condition> arg2) (goto <label> | call <macro> [<n>])

A statement with OR condition

if (arg <condition> arg2 || arg3 <condition> arg4) (goto <label> | call <macro> <n>)

A statement with AND condition

if (arg <condition> arg2 && arg3 <condition> arg4) (goto <label> | call <macro> <n>)

Or with both

if (arg <condition> arg2 || arg3 <condition> arg4 && arg5 <condition> arg6) (goto <label> | call <macro> <n>)

Where arg can be a variable, a nested variable, a special keyword, @eval or letters and numbers. <label> the name of a existing label, can only contain letters and numbers , <macro> the name of a existing macro and <n> the number of times it will call the macro. Conditions can be found on Conditions.

Note. if <n> is not defined or it's 0 it will call the macro once and stop, not continuing the first macro. If it's 1 it will run the called macro and continue the first macro. If it's bigger than 1 it will call the macro n' times and continue the first macro.

Examples

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
}

The above macro will print \$num is 1 if $num == 1, \$num is 2 if $num == 2, \$num is 3 if $num == 3. The same macro can be written using call instanted of 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
}


A more complicated macro

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 Loop

A while in macros means that certain commands will be ran while the defined conditions are met.

Syntax

while (arg <condition> arg) as <loop>
    do bla bla
    ...
end <loop>

Where arg can be a variable, a nested variable, a special keyword, @eval or letters and numbers. And <loop> the name of the loop. You can give any name you want. Conditions can be found on Conditions.


Examples

macro while {
    $i = 0
    while ($i < 10) as loop
    log \$i = $i
    $i++
    end loop
}

The result is

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


Automacros

Automacros are macro 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.

Syntax

automacro <name> {
    <conditions> <values>
    call <macro>
}

Or you can omit the call <macro>

automacro <name> {
    <condition> <values>
    call {
          <commands>
        }
}

The first syntax is usefull if you want more than one automacro to call one simple macro.

automacro First {
    <conditions> 
    call print
}
 automacro Seconds {
    <conditions> 
    call print
}
macro print {
    log $.caller triggered
}

Conditions

An Automacro needs to have at least 1 conditions or it will loop forever. It can have as many conditions you want, also some conditions automatically sets some variables so you can use them in your macros.

map <mapname>
Triggers when your current map is <mapname>.
location [not] <mapname [<x1> <y1> [<x2> <y2>]] [, ...]
Triggers when you are [not] at the specified location.

When neither <x1> <y1> nor <x2> <y2> are given it triggers when you are [not] on <mapname>. When <x2> <y2> are not given it triggers when you are [not] on <mapname> at (<x1>,<x2>). When both <x1> <y1> and <x2> <y2> are defined it triggers when you are on <mapname> somewhere between <x1>, <y1> (upper left) and <x2>, <y2> (lower right, where <x1> < <x2> and <y1> > <y2> Comma-separated arguments are treated as OR conditions:

location geffen, prontera 123 234

Triggers when you are either in geffen or in prontera at 123 234.

Multiple lines are treated as AND conditions:

location not geffen
location not prontera

Triggers when you are neither in geffen nor in prontera.


mapchange (<mapname>|any) [, ...]
Triggers when changing map to <mapname>. If the argument is any 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 baselevel 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 it's 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 - Return the actor (by player/monster) which triggered the last spell syntax on you/party member/inrange spell.
  • $.casterName - Return the name of player/monster which triggered the last spell syntax on you/party member/inrange spell.
  • $.casterID - Return the ID of player/monster which triggered the last spell syntax on you/party member/inrange spell.
  • $.casterPos - Return the last position of player/monster which triggered the last spell syntax on you/party member/inrange spell (x y).
  • $.casterSkill - Return the skill name which triggered the last spell syntax on you/party member/inrange spell.
  • $.casterTarget - Return the "location of spell" which triggered the last spell syntax on you/party member/inrange spell.
  • $.casterTargetName - Return the name of the party member that is in the range of the triggered(as a target) last spell syntax.
  • $.casterDist - Return the distance (between the caster and YOU) which triggered the last spell syntax on you/party member/inrange 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.

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 (Avaible only for monster syntax)

Comma-separated arguments are treated as OR conditions. Multiple lines are treated as AND conditions.


aggressives <condition> <number>
Triggers at <number> of aggressives.

Multiple lines are treated as AND conditions.


player ("<playername>" | /<regexp>/[i]) [, <distance> ]
Triggers when <playername> 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.


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 partychat 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 guildchat or the text received matches <regexp>.

The i switch means the regexp is case insensitive.

Set variables:

  1. $.lastguild - player's name
  2. $.lastguildMsg - player's message


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 use 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>
Triggers when defined the conditions for

Time is on 24h format.


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>
Wait 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>
Choose which automacros should be checked before others. The smaller <num> is 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 }.


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. Uou can now use perl without all the limitations from eval command.

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;
}


Comments

The macro files allow comments, i.e. lines that are ignored by the macro plugin. Lines starting with a # will be treated as comment.

macro happy {
     # this is a comment line
    log I'm Happy
}

Will print:

[log] I'm Happy


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 you used some special character on some of your macros. 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 you're using Notepad++, 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.