ขอบคุณความรู้ดีๆจาก WWW.OPENKORE.COM WWW.THAIKORE.COM WWW.OPKWIN.COM WWW.MOD2PLAY.COM และเวบอื่นๆที่ไม่ได้กล่าวถึงไว้ ณ.ทีนี้ด้วยนะคะ (ขอบคุณเป็นภาษาอังกฤษไว้ด้านบนนานแล้ว แต่เผื่ออาจมองกันไม่เห็นนะคะ เลยขอบคุณอีกรอบ)
เชิญชวนทำบุญแทนการเซทบอทให้โหลดฟรีคะ

ไม่บังคับนะคะ


แต่ใครเอาบอทไปใช้เองไม่ว่ากัน แต่ใครเอาบอทไปใช้ในทางธุรกิจ ไม่บริจาคขอให้จู้ดๆ อิอิ

ขอร้องจากใจ กรุณาอย่านำบอทไปขายเด็ดขาด ไม่ว่ากรณีใดๆทั้งสิ้น

12/05/2553

Auto Macro ALL Class

automacro {
condition 1
condition 2
……
……
call {
command 1
command 2
…..
…..
}
timeout (if necessary)
}

Change the AI mode after login to AI manual.
automacro AImanual {
 priority 1
 console /WELCOME TEXT OF THE SERVER, OR SOMETHING THAT APPEAR IN THE CHAT WHEN YOU CONNECT/
 call AImanualON
 run-once 1
}

macro AImanualON {
 pause 2
 do ai manual
 release AImanual
}

Airship Macro

macro airship {
   # Izlude, Yuno and Rachel
   # Yuno, Hugel, Einbroch and Lighthalzen - airplane
 
   $checkTransfer = True
 
   if ($.param2 == "Einbroch") goto destEinbroch
   if ($.param2 == "einbroch") goto destEinbroch
   if ($.param2 == "Hugel") goto destHugel
   if ($.param2 == "hugel") goto destHugel
   if ($.param2 == "Izlude") goto destIzlude
   if ($.param2 == "izlude") goto destIzlude
   if ($.param2 == "Lighthalzen") goto destLighthalzen
   if ($.param2 == "lighthalzen") goto destLighthalzen
   if ($.param2 == "Rachel") goto destRachel
   if ($.param2 == "rachel") goto destRachel
   if ($.param2 == "Yuno") goto destYuno
   if ($.param2 == "yuno") goto destYuno
   if ($.param2 == "Juno") goto destYuno
   if ($.param2 == "juno") goto destYuno
   goto errorDest
 
   :destEinbroch
   $airportDest = Einbroch
   goto checkStart
 
   :destHugel
   $airportDest = Hugel
   goto checkStart
 
   :destIzlude
   $airportDest = Izlude
   goto checkStart
 
   :destLighthalzen
   $airportDest = Lighthalzen
   goto checkStart
 
   :destRachel
   $airportDest = Rachel
   goto checkStart
 
   :destYuno
   $airportDest = Yuno
   goto checkStart
 
   :checkStart
   if ($.param1 == "Einbroch") goto airport
   if ($.param1 == "einbroch") goto airport
   if ($.param1 == "Izlude") goto izlude
   if ($.param1 == "izlude") goto izlude
   if ($.param1 == "Hugel") goto hugel
   if ($.param1 == "hugel") goto hugel
   if ($.param1 == "Lighthalzen") goto lhzAirport
   if ($.param1 == "lighthalzen") goto lhzAirport
   if ($.param1 == "Rachel") goto raFild12
   if ($.param1 == "rachel") goto raFild12
   if ($.param1 == "Yuno") goto yAirport
   if ($.param1 == "yuno") goto yAirport
   if ($.param1 == "Juno") goto yAirport
   if ($.param1 == "Juno") goto yAirport
   goto errorStart
 
   :checkIzludeRachel
   if ($airportDest == "Izlude") goto airshipTransfer
   if ($airportDest == "Rachel") goto airshipTransfer
   $checkTransfer = $emptyVar
   goto checkStart
 
   :checkEinbrochHugelLighthalzen
   if ($airportDest == "Einbroch") goto airshipTransfer
   if ($airportDest == "Hugel") goto airshipTransfer
   if ($airportDest == "Lighthalzen") goto airshipTransfer
   $checkTransfer = $emptyVar
   goto checkStart

   :airport
   if ($checkTransfer == "True") goto checkIzludeRachel
   do move airport
   goto quit
 
   :hugel
   if ($checkTransfer == "True") goto checkIzludeRachel
   do move 182 150 hugel
   do talk @npc (182 150)
   pause 2
   do talk resp 0
   pause 2
   do talk resp 0
   goto quit
 
   :izlude
   if ($checkTransfer == "True") goto checkEinbrochHugelLighthalzen
   do move 202 56 izlude
   do talk @npc (201 54)
   pause 2
   do talk resp 0
   pause 2
   do talk resp 0
   goto quit
 
   :lhzAirport
   if ($checkTransfer == "True") goto checkIzludeRachel
   do move lhz_airport
   goto quit
 
   :raFild12
   if ($checkTransfer == "True") goto checkEinbrochHugelLighthalzen
   do move 295 208 ra_fild12
   pause 2
   do talk resp 0
   goto quit
 
   :yAirport
   do move y_airport
   goto quit
 
   :airshipTransfer
   $airshipTransfer = True
   $checkTransfer = $emptyVar
   goto checkStart
 
   :errorStart
   log Error: Unknown starting point!
   goto quit
 
   :errorDest
   log Error: Unknown destination!
 
   :quit
}

automacro airshipEinbrochAirport {
   location airport 90 45 193 13
   timeout 90
   delay 5
   call {
      if ($airportDest == "Einbroch") goto leaveAirport
      if ($airportDest != "") goto enterTerminal
      goto quit
    
      :enterTerminal
      do move 143 38 airport
      do talk @npc (143 43)
      pause 2
      do talk resp 0
      pause 2
      do talk resp 0
      goto quit
    
      :leaveAirport
      $airportDest = $emptyVar
      do move einbroch
    
      :quit
   }
}

automacro airshipEinbrochTerminal {
   location airport 116 74 167 50
   timeout 90
   delay 5
   call {
      if ($airportDest == "Einbroch") goto leaveTerminal
      if ($airportDest != "") goto enterGate
      goto quit
    
      :enterGate
      do move 142 61 airport
      goto quit
    
      :leaveTerminal
      do talk @npc(143 51)
      pause 2
      do talk resp 0
      pause 2
      do talk resp 0
    
      :quit
   }
}

automacro airshipEinbrochGate {
   location einbroch 55 281 94 234
   timeout 90
   delay 5
   call {
      if ($airportDest == "Einbroch") goto exitGate
      if ($airportDest != "") goto enterAirship
      goto quit
    
      :enterAirship
      do move 92 280 einbroch
      goto quit
    
      :exitGate
      do move 64 234 airport
    
      :quit
   }
}

automacro airshipHugel {
   location hugel
   timeout 90
   delay 5
   call {
      if ($airportDest == "Hugel") goto arrived
      goto quit
    
      :arrived
      $airportDest = $emptyVar
    
      :quit
   }
}

automacro airshipIzlude {
   location izlude
   timeout 90
   delay 5
   call {
      if ($airportDest == "Izlude") goto arrived
      goto quit
    
      :arrived
      $airportDest = $emptyVar
    
      :quit
   }
}

automacro airshipLighthalzenAirport {
   location lhz_airport 90 45 193 13
   timeout 90
   delay 5
   call {
      if ($airportDest == "Lighthalzen") goto leaveAirport
      if ($airportDest != "") goto enterTerminal
      goto quit
    
      :enterTerminal
      do move 143 38 lhz_airport
      do talk @npc (143 43)
      pause 2
      do talk resp 0
      pause 2
      do talk resp 0
      goto quit
    
      :leaveAirport
      $airportDest = $emptyVar
      do move lighthalzen
    
      :quit
   }
}

automacro airshipLighthalzenTerminal {
   location lhz_airport 116 74 167 50
   timeout 90
   delay 5
   call {
      if ($airportDest == "Lighthalzen") goto leaveTerminal
      if ($airportDest != "") goto enterGate
      goto quit
    
      :enterGate
      do move 143 63 lhz_airport
      goto quit
    
      :leaveTerminal
      do talk @npc(143 51)
      pause 2
      do talk resp 0
      pause 2
      do talk resp 0
    
      :quit
   }
}

automacro airshipLighthalzenGate {
   location lighthalzen 294 79 309 72
   timeout 90
   delay 5
   call {
      if ($airportDest == "Lighthalzen") goto exitGate
      if ($airportDest != "") goto enterAirship
      goto quit
    
      :enterAirship
      do move 308 76 lighthalzen
      goto quit
    
      :exitGate
      do move 294 76 lighthalzen
    
      :quit
   }
}

automacro airshipraFild12 {
   location ra_fild12
   timeout 90
   delay 5
   call {
      if ($airportDest == "Rachel") goto arrived
      goto quit
    
      :arrived
      $airportDest = $emptyVar
    
      :quit
   }
}

automacro airshipYunoAirport {
   location y_airport 90 45 193 13
   timeout 90
   delay 5
   call {
      if ($airportDest == "Yuno") goto leaveAirport
      if ($airportDest != "") goto enterTerminal
      goto quit
    
      :enterTerminal
      do move 143 38 y_airport
      do talk @npc (143 43)
      pause 2
      do talk resp 0
      pause 2
      do talk resp 0
      goto quit
    
      :leaveAirport
      $airportDest = $emptyVar
      do move yuno
    
      :quit
   }
}

# Left 141 63: Izlude Yuno Rachel
# Right 144 63 : Yuno Hugel Einbroch Lighthalzen
automacro airshipYunoTerminal {
   location y_airport 116 74 167 50
   timeout 90
   delay 5
   call {
      if ($airportDest == "Yuno") goto leaveTerminal
      if ($airportDest != "") goto enterGate
      goto quit
    
      :enterGate
      if ($airportDest == "Izlude") goto leftGate
      if ($airportDest == "Rachel") goto leftGate
      if ($airportDest == "Hugel") goto rightGate
      if ($airportDest == "Einbroch") goto rightGate
      if ($airportDest == "Lighthalzen") goto rightGate
      goto quit
    
      :leftGate
      do talk @npc (141 63)
      pause 2
      do talk resp 0
      goto quit
    
      :rightGate
      do talk @npc (144 63)
      pause 2
      do talk resp 0
      goto quit
    
      :leaveTerminal
      do talk @npc(143 51)
      pause 2
      do talk resp 0
      pause 2
      do talk resp 0
    
      :quit
   }
}

automacro airshipYunoLeftGate {
   location yuno 5 279 51 238
   timeout 90
   delay 5
   call {
      if ($airportDest == "Yuno") goto exitGate
      if ($airshipTransfer == "True") goto transferedAirships
      if ($airportDest != "") goto enterAirship
      goto quit
    
      :enterAirship
      do move 8 261 yuno
      goto quit
    
      :transferedAirships
      $airshipTransfer = "False"
    
      :exitGate
      do move 52 238 yuno
    
      :quit
   }
}

automacro airshipYunoRightGate {
   location yuno 56 279 97 238
   timeout 90
   delay 5
   call {
      if ($airportDest == "Yuno") goto exitGate
      if ($airshipTransfer == "True") goto transferedAirships
      if ($airportDest != "") goto enterAirship
      goto quit
    
      :enterAirship
      do move 97 260 yuno
      goto quit
    
      :transferedAirships
      $airshipTransfer = "False"
    
      :exitGate
      do move 55 238 yuno
    
      :quit
   }
}

automacro airshipLanded {
   #console /The Airship is leaving the ground. Our next destination is (.*)./
   #console /We are heading to (.*)./
   console /We will arrive in (.*) shortly./
   #console /Welcome to (.*). Have a safe trip./ 
   call {
      if ($airportDest == $.lastMatch1) goto exitAirport
      if ($.lastMatch1 == "Juno") goto checkYuno
      if ($airshipTransfer == "True") goto checkTransfer
      goto quit
    
      :checkTransfer
      if ($.lastMatch1 == "Yuno") goto exitAirport
      if ($.lastMatch1 == "Juno") goto exitAirport
      goto quit
    
      :checkYuno
      if ($airportDest == "Yuno") goto exitAirport
      if ($airshipTransfer == "True") goto checkTransfer
      goto quit
    
      :exitAirport
      do move 243 74
    
      :quit
   }
}

Trades/Party:

automacro Party {
console /Incoming Request/i
call noparty
run-once 1
}
macro noparty {
pause 1
do e shy
pause 1
do c @random ("?","text","bla")
pause 1
release Party
}


automacro Deal {
console /Requests a Deal/i
call noDeal
run-once 1
}
macro noDeal {
pause 1
do e hmm
pause 1
release Deal
}

automacro strip {
status Strip Weapon
call {
do tele
do relog 10
}
timeout 10
}

#####Bot does not use Butterfly Wings, if he has no######

automacro justwalk {
console /You don't have the Teleport skill or a Butterfly Wing/i
run-once 1
call {
do conf saveMap_warpToBuyOrSell 0
}
}

######Bot Butterfly Wings used instead of running######

automacro whywalkwhenyoucanfly {
inventory Butterfly Wing => 1
run-once 1
call {
do conf saveMap_warpToBuyOrSell 1
}
}

Thx say at Heal / buff

automacro support {
console /uses Heal on you/i
call thx
timeout 100
run-once 1
}
macro thx {
pause 1
do e thx
release support
}

Macro Repair

automacro betulin{
inventory "BROKEN (Barang yg hancur)" > 0
call sss
delay 3
timeout 1800
}
macro sss {
respawn
@pause 4
move 126 59
@pause 1
talk @npc (120 62)
@pause 2
talk cont
@pause 2
talk resp 2
@pause 2
talk cont
@pause 2
talk resp 0
@pause 4
move 60 65 prt_in
@pause 2
talk @npc (63 54)
@pause 2
talk cont
@pause 2
talk resp 0
@pause 2
talk cont
@pause 2
talk resp 0
@pause 1
eq @inventory (Nama Equip)
move prontera
respawn
}

macro ver 0.9.3
config.txt: autoTalkCont 0

Note:* Special simpos at the Geffen!

Macro Logout char lewat whisp

automacro quit {
pm out|UserNameHere
delay 5
call Omfg
}
macro Omfg {
pm "UserNameHere" Okay, im leaving now !!
quit
}

Macro Heal & paket dengan Pub

automacro HealPub {
pubm /heal/i
call {
do sp 28 @player($.lastpub)
}
}

automacro PaketPub {
pubm /paket|pkt|pket|pakt/i
call {
do sp 34 @player($.lastpub)
do sp 29 @player($.lastpub)
}
}

automacro buff {
pubm /hui/
run-once 1
exclusive 1
call paket
}
macro paket {
$jarak = $.lastMatch1
$player = $.lastMatch2
$no = $.lastMatch3
if ($jarak > 6) goto jauh
do c "sabar yach.. lg maketin $player"
#skill blessing
do sp 34 $no 10
#skill increase agi
pause 0.5
do sp 29 $no 10
#skill assumptio
pause 1
do sp 73 $no 10
goto end
:jauh
do c "Hey $ player here deket-deket Aq, jgn jauh2 dong klo say want to ask the package ^_^"
:end
release buff
}

auto d coment want tambahiin want d gmniin? if not d tambahiin comment cation stiap out packagesection

#skill blessing
do sp 34 $no 10
#skill increase agi
pause 0.5
do sp 29 $no 10
#skill assumptio
pause 1
do sp 73 $no 10
do c Patience y Sayank....
do c jgn a hurry .... Mojok here with me first.
goto end

Kak skynozzMacro killLogo kk said I should try macrosfinally I try and learnafter it came out problemthat he always beat players in the first place in the Player listthis macronya

automacro fisik {
set macro_delay 0.1
set orphan reregister
timeout 2
console /Player (.*) \((\d+)\) attacks you.*/i
call kill
}
automacro magic {
set macro_delay 0.1
set orphan reregister
timeout 2
console /Player (.*) \((\d+)\) menggunakan (.*) pada anda*/i
call kill
}
macro kill {
log $.lastMatch1 ($.lastMatch2) attacked you!
do kill $.lastMatch1
}

try on the $. lastMatch1 d replace the same $. lastMatch3 His problem is only the first order just kill you?

automacro paket 1 {
pm ehe/
do c Oke!!
call {
$ro = @player ($.lastpm)
do sp 34 $ro
pause 0.5
do sp 29 $ro
pause 1.2
do sp 361 $ro
}
}

kk kk all who champion macros please help me 34 my code skills "Increase AGI" in Macro29 my code skills "Blessing" in Macro361 my code skills "Assumptio" in Macro how tough it List 2 skill where the hell?

AutoMacro No Sp {
sp < 95%
location gefenia01
timeout 5
call {
do c @ load [OR DO IS 38] <<<<< To respawn at the save point (38 = bfw) [/ i]
do talknpc [X] [Y] sequence    ('n' if it is just a click) <<<<< Coordinated the healer, and the sequence
}
}

AutoMacro FullHP "City respawn" {
location "City respawn"
hp <95%
timeout 10
call {
do talknpc [X] [Y] sequence ('n' if it is just a click)
}
}

automacro sp {
sp < 200
call {
do c sp low
}
timeout 10
}

partySkill 34 {
lvl 10
sp > 10%
target "Name Me to buff"
target_timeout 10
}

partySkill 29 {
lvl 10
sp > 10%
target "Name Me to buff"
target_timeout 10
}

macro foo {
$foobegin = $.pos
do move 168 128 prt_in
do talk @npc (172 130)
do store
do store
do buy
@store (Silver Arrow) 10000
do move 280 198 prontera
do talk @npc (282 200)
do talk cont
do talk resp 1
do storage add @inventory (Silver Arrow) @eval (@invamount (Silver Arrow) - 1000)
do move $foobegin
}

This macro is made by someone who plays for xkore1 nihzhe
There must be a party to Otobrozheniya lessons learned quite a time to write in a party showexp

automacro opit {
party "showexp"
call {
log Enabled Sschetchik experience
}
call showexp1
}
macro showexp1 {
$ A = @ eval ($:: char-> {exp})
$ B = @ eval ($:: char-> {exp_job}
do exp reset
log Sbroshet Report on experience
# Writing for a period of time, in seconds, ############
pause 30
call showexp2
}

macro showexp2 {
$c = @eval($::char->{exp})
$e = @eval($::char->{exp_job})
$a1 = @eval($::char->{exp_max})
$a2 = @eval($::char->{exp_job_max})
$d = @eval($c - $a)
$d1 = @eval(($c - $a)/$a1)
$f = @eval($e - $b)
$f1 = @eval(($e - $b)/$a2)
if ($a2 < 400000000) goto end
$f1 = 0
:end
if ($a1 < 400000000) goto end2
$d1 = 0
:end2
if ($f != 0) goto end3
call showexp1
:end3
if ($d != 0) goto end4
call showexp1
:end4
database do p $ d ($ d1%) Jobe $ f ($ f1%)
pause 1
call showexp1
}

pause 30 shows the experience two times in a minute
change if necessary, and Correction for themselves Putting Less than 20 is not recommended! Including protection from the last lvl and Job. Protection is turned on you have not received 1 cycle of experience and then continued. NOT IMPORTANT WHERE DOES THE TEAM @ SHOWEXP

Macro to play on a tote for the server.

Playing on a single and a double race.
You can upload one assembly with a set of macro plugin and this macro.
Link to download the finished assembly: hugel races

For those who do not want to use the finished assembly can download an archive of macro embedding.

What can I get for these chips?

These awards are obtained from an NPC in Hugele, next to the Sweepstakes.

* 1 token:

2 Hinalle Leaflet
2 Aloe Leaflet
1 Mastela Fruit
5 Witched Starsand
4 Condensed Red Potion

* 3 tokens:

1 Royal Jelly
6 Holy Water

* 7 tokens:

1 Bundle of Food
1 First Aid Kit

* 8 chips:

1 Gift Bo

* 16 tokens:

1 Old Blue Box

* 25 tokens:

1 Taming Gift Set

* 42 tokens:

1 Old Purple Box

* 59 tokens:

1 Poring Box

These awards are obtained from NPC at the factory Eynbroha (208, 85).

* 500 chips:
Glittering Jacket [1]

* 1000 tokens:

Lucius's Fierce Armor of Volcano [1]
Aebecee's Raging Typhoon Armor [1]
Claytos Cracking Earth Armor [1]
Saphien's Armor of Ocean [1]

* 1500 tokens:

macros.zip

Weapon Level 4, the full list here.

automacro goermfeeeeeed {
call {
log homun hunger: @eval($::char->{'homunculus'}{'hunger'})
$i = @eval($::char->{'homunculus'}{'hunger'})
if ($i < 25) goto fee
goto end
:fee
do homun feed
:end
}
timeout 180
}

automacro gomfeed {
eval $::char->{'homunculus'}{'hunger'} eq "24"
call {
log Feeding gom!
do homun feed
}
}

In the config should be rows:

Fill in all the values in the macro plant by itself (remember that the initial coordinates should be less than the final).

Then just run the macro each time the plant will need to plant the rectangle that you specify.

From my collection

UPDATE

Updated to version 1.1.

1) The macro is optimized.

2) Fixed bug with stopping a macro when a skill for some reason goes astray.

3) Dolan checking for ch.

If no, sit until it is at least 100 (this number is specified in the variable $ sptocon - change if needed).

Notes:

Not mounted on the preponderance test during recovery cn. Until this is done try not to be nubami ....

Recently decided to make a macro to bot at the request came to the goblet (LGU for example) - can anyone come in handy

automacro come {
pubm / Come /i
run-once 1
call {
do ai manual
pause 1
$id = @player ($.lastpub)
$x = @eval ($::players{$::playersID[$id]}->{pos_to}{x})
$y = @eval ($::players{$::playersID[$id]}->{pos_to}{y})
$x = @eval($x + @random("-1","1"))
$y = @eval($y + @random("-1","1"))
do move $x $y
pause 10
release come
do ai on
}
}

Useful elements used here on the site I'm nowhere in the descriptions of the macro plugin did not see

Code:
$:: Players

Or

Code:
$:: Char

So that these examples help to expand the language for writing macros, thanks to a

This is only usable if you are stalker/sinx, and if you're playing in a non-instant cast server.

automacro hide {
    
exclusive 1
    run
-once 1
    spell Extremity Fist
    
# check out the right name of the spell in tables/skills.txt
    
call {
        [
        
#do eq Clip [Smokie] [1] <-- if you're not stalker/sinx
        
do ss ## <-- here you put the number of the skill
        
release hide
        
]
    }

It fails if you're not stalker/sinx because macro tells openkore to equip your hiding clip and then use hiding skill. This isn't done fast enough. In practice openkore tries to use hiding skill but asura hits you before.

Even if you're playing a stalker/sinx, it won't save your ass in some situations, like right after a sonic blow (you'll suffer the delay time and you won't be able to use hiding for a while) or a champion with ruwach.

automacro SW {
exclusive 1
run-once 1
spell Extremity Fist
# check out the right name of the spell in tables/skills.txt
call {
do ss 12 /This is the skill# in the skills.txt for Safety Wall/
release SW
}
}

If your cast time is faster than your enemy's cast time, yes, it'll work.
Put these conditions to prevent any console errors:
...
spell Extremity Fist
inventory "Blue Gemstone" > 0
sp > x
call
...

automacro EF {
exclusive 1
spell Extremity Fist
call defendEF
run-once 1
}
macro defendEF {
do sp/Skill on Player? i see it on the macro manual/ 289/Skill# for Dispell/
release EF
}

Changes the equip you want to defend freeze, you can do this with all other skills/eq too, the skills and equip have to be spelled in the same way they are in the tables/skills.txt, for eq you have to look in the Openkore console and write "eq" or "i" to the the names, they can be very different from your known names.
You should not change your headgear if it have another appearence then the headgear before, players would see this.

Code:

automacro freeze {
 exclusive 1
 spell Storm Gust, Frost Nova, Frost Joke, Frost Diver, Hyousyouraku
 call defendfreeze
 run-once 1
}

macro defendfreeze {
[
 do eq #YOUR EXACT HEADGEAR NAME e.g +10 Fricca's Circlet, best if it is magic defence, because spells are the only noticeable things that appear in the console
 do eq #YOUR ANTI FREEZE/AQUA ARMOR UPPER HEADGEAR, MDEF would be best.
 do eq #YOUR ANTI FREEZE/AQUA ARMOR LOWER HEADGEAR, MDEF would be best.
 do eq #YOUR ANTI FREEZE/AQUA ARMOR SHIELD , MDEF would be best.
 do eq #YOUR ANTI FREEZE/AQUA ARMOR GARMENT , MDEF would be best.
 do eq #YOUR ANTI FREEZE/AQUA ARMOR, MDEF would be best.
 do eq #YOUR ANTI FREEZE/AQUA ARMOR SHOES, MDEF would be best.
 do eq #YOUR ANTI FREEZE/AQUA ARMOR ACCESSORY , MDEF would be best.
 do eq #YOUR ANTI FREEZE/AQUA ARMOR ACCESSORY , MDEF would be best.
 release freeze
]
}

Example:
Code:
automacro fire {
 exclusive 1
 spell Fire Bolt, Meteor Storm, Kouenka
 call defendfire
 run-once 1
}

macro defendfire {
[
 do eq +10 Fricca's Circlet
 do eq Unknown #30105 [Gibbet]
 do eq Unknown #30287 [Marduk]
 do eq +10 Valkyrja's Shield [Thara Frog] [1]
 do eq Ragamuffin Manteau
 do eq Odin's Blessing [Pasana] [1]
 do eq Crystal Pumps
 do eq Rosary [Horong] [1]
 do eq Rosary [Smokie] [1]
 release fire
]

}
 hep hep hep!!! dont forget the auto-thanks

Code:
automacro auto-thanks {
   exclusive 1
   console /Heal|Blessing|Increase AGI|Impositio Magnus|Aspersio on you/i
   timeout 30
   run-once 1
   exclusive 1
   call {
      $accolade = @random ("e thx","c thx","c ty","c thanks ^^","c w00t","c yay","c ty!","c thanks!")
      pause 1
      do $accolade
      release auto-thanks
   }
}

console /Heal|Blessing|Increase AGI|Impositio Magnus|Aspersio on you/i

he says "Thank" or "ty" when he loses his buffs >_< ! Ahemm ... he says "Thx" too when another players on the screen use the same things.
It should
console /(Heal|Increase AGI|Blessing|Assumption) on you/i

or, a bigger one

console /(Player (.*)|Unknown #(.*)|\[GM\](.*)) uses (Heal|Increase AGI|Blessing|Assumption) on you/i

It should work.
#######################################################
#   Teleporting using Fly-wing for emergency

automacro teleNow {
console /.*Teleporting to avoid (Salamander|Bow Master|Sword Master)|dmg could kill you|or too many aggressives*/i
inventory "Fly Wing" >= 1
overrideAI 1
run-once 1
call {
do is Fly Wing
release teleNow
}
}

#######################################################
#   Teleporting using Butterfly-wing for autostorage
automacro AutoStorage {
   console /.*Calculating auto-storage route to:*/i
   inventory "Butterfly Wing" >= 1
   overrideAI 1
   run-once 1
   call  {
      do is Butterfly Wing
      release AutoStorage
   }
}

this macro is Auto-Ignore people caught you botting...

automacro dangerPub {
   console /\[dist=(.*)\] (.*) \((\d+)\): (.*)([Bb][Oo][Tt]|[Bb][0][Tt]|[Ss][Ee][Tt]|[Kk][Oo][Rr][Ee]|[Cc][Hh][Ee][Aa][Tt])(.*)$/
   run-once 1

   call {
      $dist = $.lastMatch1
      $BadGuys = $.lastMatch2
      if ($dist > 7) stop

      log replying to PubMsg in 7 sec!
      $accoladeEmo = @random ("e omg","e desp","e spin","e meh","e ?")
      do $accoladeEmo
      pause 7

      $accoladeSpeak = @random ("pm $BadGuys its called openkore","pm $BadGuys wht???","pm $BadGuys wht do you mean","pm $BadGuys really ^^","pm $BadGuys w00t","pm $BadGuys yay","pm $BadGuys =) ")
      pause 1
      do $accoladeSpeak

      do ignore 1 $BadGuys

      release dangerPub
   }
}

soon player buff the monster... BAD BAD BAD PLAYER!!!

console /\Player (.*) \((\d+)\) uses Heal|Blessing|AGI on monster (.*) \((\d+)\) :\*\*$/i

update the macro first to trigger this...

this update will increase the power of your eval... and it will help you a lot...
thanks for DInvalid and piroJOKE for sharing this macro code...

Code:
--- e:\svn-openkore\macro\trunk\Macro\Data.pm   Sat Sep 01 09:27:13 2007
+++ c:\333333333\Data.pm   Mon Jan 14 17:05:27 2008
@@ -35,5 +35,7 @@
   'hook' => 1,         # check: openkore hook
   'priority' => 1,     # option: automacro priority
   'exclusive' => 1,     # option: is macro interruptible
   'eval' => 1        # check : eval
);


Code:
--- e:\svn-openkore\macro\trunk\Macro\Automacro.pm   Sat Sep 01 09:27:13 2007
+++ c:\333333333\Automacro.pm   Mon Jan 14 17:04:13 2008
@@ -321,4 +321,10 @@
}

+# checks for eval
+sub checkEval {
+   return eval $_[0];
+}
+
+
# releases a locked automacro ##################
sub releaseAM {
@@ -425,4 +431,6 @@
      next CHKAM if (defined $automacro{$am}->{class}  && !checkClass($automacro{$am}->{class}));
      next CHKAM if (defined $automacro{$am}->{notMonster} && !checkNotMonster($automacro{$am}->{notMonster}));
+      next CHKAM if (defined $automacro{$am}->{eval} && !checkEval($automacro{$am}->{eval}));
+
      foreach my $i (@{$automacro{$am}->{monster}})    {next CHKAM unless checkMonster($i)}
      foreach my $i (@{$automacro{$am}->{aggressives}}){next CHKAM unless checkAggressives($i)}

while sitting you will do doridori...
automacro doridori {
   eval $::char->{sitting} == 1 && !AI::inQueue("macro")
   sp < 90%
   timeout 2

   call {
      do doridori
   }
}

Self defense

killing attacker while attacked 1st

Code:
automacro dipukul {
console /Player (.*) \((\d+)\) attacks you.*/i
call {
do kill $.lastMatch2
}
}

automacro dimagic {
console /Player (.*) \((\d+)\) uses (.*) on you - Dmg.*/i
call {
do kill $.lastMatch2
}
}

automacro dicast {
console /Player (.*) \((\d+)\) is casting (.*) on you.*/i
var .lastMatch1 != PutSlaveNameHereRemoveThisLineIfBottingSolo
call {
do kill $.lastMatch2
}
}

Hit list

 autokill when certain player nearby, using these while having a slave priest in certain pvp server may result in killing your own priest due to some pvp server allows interguild and interparty fight so be careful
in certain state macros wont released by itself due failing on killing other ppl, so we need another macro as a precautious statement just in case

Code:
automacro bunuh {
run-once 1
player "playerA"
call {
release jaga2
do kill $.lastplayer
release bunuh
}
}

automacro bunuh2 {
run-once 1
player "playerB"
call {
release jaga2
do kill $.lastplayer
release bunuh2
}
}

automacro jaga2 {
run-once 1
console /Can't reach or damage target/i
call {
release bunuh
release bunuh2
}
}

Another hit list

shorter version yet cant be used against players with asterisks (*) on their name example **roplayer**

Code:
automacro bunuh {
run-once 1
exclusive 1
player /PlayerA|PlayerB|PlayerC/i
call {
do kill $.lastplayer
release bunuh
}
}

automacro jaga2 {
run-once 1
console /Can't reach or damage target/i
call {
release bunuh
}
}

auto kill

my favourite up until recently, kills certain job only (thx mushroom for helping me out on this 1). the example below will do autokill on every monk/champion job nearby, change the if ($job = Champion) goto kill part or add new 1 below those to adding new job example Lord Knight or Hunter

Code:
automacro check-PK {
player /(.*)/
run-once 1
exclusive 1
timeout 5
call {
       $job = none
      do eval foreach my $_player (@{$::playersList->getItems()}) {next unless ($_player->{'binID'} eq "$::Macro::Data::varStack{pl}"); $::Macro::Data::varStack{job} = ($::players{$::playersID[$_player->{binID}]}->job);}
      if ($job = Champion) goto kill
      if ($job = Monk) goto kill
      release check-PK
      stop
      :kill
      do kill $.lastplayer
      release check-PK
      }
}

invalid monsters macro

dced while meets a mob who shouldnt be there, works on anything, even porings and planktons who summoned by dead branch, check the appropriate monsters by checking maps on ratemyserver.net, sample below are ein_fild04 (dont remove the monsters after Wild Rose and after, Wild Rose is almost on each and every town, Wild Gift Box is occasionally appeared in events and the rest are bodyguards name in openkore console)

Code:
automacro gasudi {
run-once 1
notMonster Geographer, Metaling, Mineral, Holden, Giearth, Red Plant, Green Plant, Yellow Plant, Wild Rose, Wild Gift Box, Jakk Xmas, Gobline Xmas, Christmas Orc, Antonio, David, Ellen, Luise, Frank, Ryan, Paolo, Jens, Thierry, Steven, Wayne, Mina, Dorou, Nami, Elfin, Clara, Dali, Karaya, Hiyori, Kero, Sukye, Rodin, Lancer, Nathan, Roan, Orizaro, Thyla, Ben, Pinaka, Kuhlmann, Roux
call {
do relog 1500
release gasudi
}
}

Macro sent u back to ur save position,if u memo ur training ground.

edit the do warp line

Code:
automacro kesasar {
run-once 1
location not PutTrainingMapHere, PutKafraMapHere, PutAdditionalMapPathHere
timeout 60
call {
do g gawat saya di $.map koordinat $.pos
release kesasar
}
}

automacro warpbalik {
run-once 1
inventory "Blue Gemstone" > 0
guild /gawat saya di (.*) koordinat (.*) (.*)/i
call {
do sl 27 @eval ($.lastMatch2 + 3) $.lastMatch3
pause 2
do warp 0
pause 5
do move @eval ($.lastMatch2 + 3) $.lastMatch3
release warpbalik
}
}

gift box & old blue box bot
copy this in ur config

Code:
# Please Read the Users Manual
# The Manual is located at http://openkore.sourceforge.net/manual/

######## Login options and server-specific options ########

master Indonesia - idRO: Thor
server 1
username
password
pin
char 0
sex

bindIp
# For an overview of all servertypes please go to the following URL:
# http://www.openkore.com/wiki/index.php/ServerType#English
serverType 21

# 1 = hook into RO client, 2 = Act as stand-alone proxy, proxy = act as true proxy
XKore 0
XKore_silent 1
XKore_bypassBotDetection 0
XKore_exeName ragexe.exe

# XKore 2 / Proxy configuration
XKore_ID
XKore_listenIp 127.0.0.1
XKore_listenPort 6901
XKore_publicIp 127.0.0.1
XKore_proxyAllowed_IP

# It is not advised to set secureAdminPassword if you're using Xkore 2
secureAdminPassword 1
adminPassword vanatwes
callSign
commandPrefix ;

pauseMapServer 0
ignoreInvalidLogin 0
secureLogin_requestCode

message_length_max 80

######## Main configuration ########

alias_heal sp 28

allowedMaps
allowedMaps_reaction 1

attackAuto 0
attackAuto_party 0
attackAuto_onlyWhenSafe 0
attackAuto_followTarget 1
attackAuto_inLockOnly 1
attackDistance 1
attackDistanceAuto 1
attackMaxDistance 1
attackMaxRouteDistance 100
attackMaxRouteTime 4
attackMinPlayerDistance 2
attackMinPortalDistance 4
attackUseWeapon 1
attackNoGiveup 0
attackCanSnipe 0
attackCheckLOS 0
attackLooters 2
attackChangeTarget 1
aggressiveAntiKS 0

autoMoveOnDeath 0
autoMoveOnDeath_x
autoMoveOnDeath_y
autoMoveOnDeath_map

autoBreakTime {
   startTime
   stopTime
}

autoConfChange {
   minTime
   varTime
   lvl
   joblvl
}

autoMakeArrows 0

autoRestart 0

autoRestartMin 10800
autoRestartSeed 3600

autoRestartSleep 0
autoSleepMin 900
autoSleepSeed 900

autoResponse 0

autoSpell

avoidGM_near 0
avoidGM_near_inTown 0
avoidGM_talk 0
avoidGM_reconnect 1800
avoidGM_ignoreList

avoidList 0
avoidList_inLockOnly 1
avoidList_reconnect 30

cachePlayerNames 1
cachePlayerNames_duration 900
cachePlayerNames_maxSize 100

clientSight 20

itemsTakeAuto 2
itemsTakeAuto_party 1
itemsGatherAuto 2
itemsMaxWeight 75
itemsMaxWeight_sellOrStore 75
itemsMaxNum_sellOrStore 99
cartMaxWeight 7900

lockMap
lockMap_x
lockMap_y
lockMap_randX
lockMap_randY

route_escape_unknownMap 1
route_escape_reachedNoPortal 1
route_escape_randomWalk 0
route_escape_shout
route_randomWalk 0
route_randomWalk_inTown 0
route_randomWalk_maxRouteTime 75
route_maxWarpFee
route_maxNpcTries 5
route_teleport 0
route_teleport_minDistance 150
route_teleport_maxTries 8
route_teleport_notInMaps
route_step 15

runFromTarget 0
runFromTarget_dist 6

saveMap
saveMap_warpToBuyOrSell 1
saveMap_warpChatCommand

shopAuto_open 0
shop_random 0

sitAuto_hp_lower
sitAuto_hp_upper
sitAuto_sp_lower
sitAuto_sp_upper
sitAuto_over_50 0
sitAuto_idle 0

statsAddAuto 0
statsAddAuto_list
statsAddAuto_dontUseBonus 0
statsAdd_over_99 0

skillsAddAuto 0
skillsAddAuto_list

tankMode 0
tankModeTarget

dealAuto 1
dealAuto_names
partyAuto 2
partyAutoShare 1
guildAutoDeny 1

verbose 1
showDomain 0
squelchDomains
verboseDomains
beepDomains
beepDomains_notInTown

logChat 0
logPrivateChat 1
logPartyChat 1
logGuildChat 1
logSystemChat 1
logEmoticons
logConsole 0
logAppendUsername 1

chatTitleOversize 0
shopTitleOversize 0

sleepTime 10000
intervalMapDrt 1

ignoreAll 1
itemHistory 0
autoTalkCont 1
noAutoSkill 0
portalRecord 2
missDamage 0

tankersList

removeActorWithDistance

useSelf_item Gift Box, Old Blue Box, Red Envelope {
   hp < 100000
   sp
   homunculus_hp
   homunculus_sp
   homunculus_dead
   onAction
   whenStatusActive
   whenStatusInactive
   whenFollowing
   spirit
   aggressives
   monsters
   notMonsters
   stopWhenHit 0
   inLockOnly 0
   notWhileSitting 0
   notInTown 0
   timeout 0
   disabled 0
   inInventory
   manualAI 0
}

######## Autostorage/autosell ########

sellAuto 1
sellAuto_npc payon 159 96
sellAuto_standpoint
sellAuto_distance 5

storageAuto 1
storageAuto_npc payon 181 104
storageAuto_distance 5
storageAuto_npc_type 3
storageAuto_npc_steps c r1 n
storageAuto_password
storageAuto_keepOpen 0
storageAuto_useChatCommand
relogAfterStorage 0

getAuto Gift Box {
   minAmount 1
   maxAmount 100
   passive
}

######## Debugging options; only useful for developers ########

debug 0
debugPacket_unparsed 0
debugPacket_received 0
debugPacket_ro_sent 0
debugPacket_sent 0
debugPacket_exclude
debugPacket_include
debugPacket_include_dumpMethod
debugDomains
storageEncryptKey 0x050B6F79, 0x0202C179, 0x00E20120, 0x04FA43E3, 0x0179B6C8, 0x05973DF2, 0x007D8D6B, 0x08CB9ED9
gameGuard 1
serverEncoding Western
m
macro_orphans terminate
#<syntax> <distance>
#This is compulsary and will trigger only if $actorDist <= maxPlayerDist
maxPlayerDist 10

and this is for the items_control
Code:
all 0 0 1
Gift Box 1 0 0
Old Blue Box 0 1 0
Old Purple Box 0 1 0
Gold 0 1 0
Heroic Emblem 0 1 0
Alcohol 0 1 0
Karvodailnirol 0 1 0
Oridecon 0 1 0
Elunium 0 1 0
Osiris Doll 0 1 0
Yoyo Doll 0 1 0
Fang of Hatii 0 1 0
Rough Oridecon 0 1 0
Rough Elunium 0 1 0
Steel 0 1 0
Emperium 0 1 0
Haedonggum [2] 0 1 0
Saber [3] 0 1 0
Two-handed Sword [2] 0 1 0
Gladius [3] 0 1 0
Damascus [2] 0 1 0
Katar of Frozen Icicle 0 1 0
Katar of Quaking 0 1 0
Katar of Raging Blaze 0 1 0
Katar of Piercing Wind 0 1 0
Orcish Axe 0 1 0
Soul Staff 0 1 0
Chain [3] 0 1 0
Mighty Staff 0 1 0
Evil Bone Wand 0 1 0
Arbalest [2] 0 1 0
Gakkung Bow [2] 0 1 0
Guard [1] 0 1 0
Buckler [1] 0 1 0
Shield [1] 0 1 0
Mirror Shield [1] 0 1 0
Memory Book 0 1 0
Bunny Band 0 1 0
Helm [1] 0 1 0
Sweet Gent 0 1 0
Romantic Gent 0 1 0
Golden Gear 0 1 0
Western Grace 0 1 0
Coronet 0 1 0
Monk Hat 0 1 0
Wizard Hat 0 1 0
Angel Wing 0 1 0
Evil Wing 0 1 0
Iron Cain 0 1 0
Spiky Band 0 1 0
Cigarette 0 1 0
Pipe 0 1 0
Romantic Flower 0 1 0
Romantic Leaf 0 1 0
Ghost Bandana 0 1 0
Apple of Archer 0 1 0
Pirate Bandana 0 1 0
Blinker 0 1 0
Orc Helm 0 1 0
Mink Coat [1] 0 1 0
Full Plate [1] 0 1 0
Lord's Clothes [1] 0 1 0
Silk Robe [1] 0 1 0
Tights [1] 0 1 0
Ninja Suit 0 1 0
Pantie 0 1 0
Legion Plate Armor [1] 0 1 0
Crystal Pumps 0 1 0
High Heels 0 1 0
Boots [1] 0 1 0
Shoes [1] 0 1 0
Muffler [1] 0 1 0
Manteau [1] 0 1 0
Ancient Cape 0 1 0
Ragamuffin Manteau 0 1 0
Greaves [1] 0 1 0
Ring [1] 0 1 0
Earring [1] 0 1 0
Necklace [1] 0 1 0
Glove [1] 0 1 0
Brooch [1] 0 1 0
Rosary [1] 0 1 0
Clip [1] 0 1 0
Jewel Crown 0 1 0
Joker Jester 0 1 0
Fin Helm 0 1 0
Goblin Leader Mask 0 1 0
Panda Hat 0 1 0
Poring Hat 0 1 0
Small Ribbons 0 1 0
Ring 0 1 0
Earring 0 1 0
Necklace 0 1 0
Glove 0 1 0
Brooch 0 1 0
Red Envelope 0 1 0
Golden Bell 0 1 0
Queen's Hair Ornament 0 1 0

this will works once ur character bring at least 2 or more gift box (lets just bring 100 just to be safe) that way whenever it lacks of those it will continue doing autostorage, selling the craps until ur running out of gift boxes. the items control however, it contains important stuff on gift box AND old blue box, so u can uses the same config, simply change the getAuto on config into old blue box

i adjust the items control only on my needs, so if u feel like needing extra items such as Witherless Rose, u might need to ad extras on ur own

Macro for avoiding death for servers w/o tele

automacro tele {
exclusive 1
aggressives >= 2
hp < 20%
call {
do tele
}
}

and edit config sitAuto_hp_lower 25% # or like this. Do sit to restore hp.
for severs w/o tele

automacro RelogMe {
run-once 0
aggressives >= 2
hp < 20%
call {
do relog 60
}
}

macro Basically hides when a particular skill (e.g. Water Ball). Whenever you are being targeted by a particular skill your Rogue/Assasin hides!

automacro hide {
exclusive 1
run-once 1
spell Water Ball
# check out the right name of the spell in tables/skills.txt
call {
do ss 51
pause 20
do ss 51
release hide {
]
}
}

Alberta Daily Cargo Quest Macro

this is for pinoy out there tired of walking back en forth around alberta

just set your characters in changeCHAR macro
the default number of char is 5, just edit the macro if you want to add

this code is not mine, thanks to the persons who make the code you know who you are if you are reading this.

i just added change character

Code:
######AUTOMACROS#########

automacro MOVEtoALBERTA {
   location not alberta
   call {
      do move alberta
   }
   timeout 60
}

#START THE QUEST
automacro STARTQUEST {
   console /Your Coordinates:/
   location alberta
   call PORTNPC
   timeout 5
}

#END TALKING TO MIMIC
automacro ENDmimic1 { 
   console /before it changes its mind/
   call PORTNPC
   timeout 5
}

automacro ENDmimic2 { 
   console /have already moved/
   call PORTNPC
   timeout 5
}

# TALK TO MIMIC AGAIN
automacro RETALKmimic {
   location alberta
   console /Deadly Cargo (.*) That/
   call retalkMIMIC
   timeout 0
}

#go to mimic
automacro MIMIC1-a {
   console /recognize the first crate/
   call {
      $mimic = first
      call talkMIMIC
   }
   timeout 5
}

automacro MIMIC1-b {
   console /get me the first crate/
   call {
      $mimic = first
      call talkMIMIC
   }
   timeout 5
}

automacro MIMIC2-a {
   console /retrieve the second crate/ 
   call {
      $mimic = second
      call talkMIMIC
   } 
   timeout 5
}

automacro MIMIC2-b {
   console /get me the second crate/
   call {
      $mimic = second
      call talkMIMIC
   }
   timeout 5
}



automacro MIMIC3-a {
   console /third crate should be with/
   call {
      $mimic = third
      call talkMIMIC
   }
   timeout 5
}

automacro MIMIC4-a {
   console /get me the fourth crate/
   call {
      $mimic = fourth
      call talkMIMIC
   }
 
   timeout 5
}

automacro MIMIC5-a {
   console /find the fifth crate/
   call {
      $mimic = fifth
      call talkMIMIC
   } 
 
   timeout 5
}

automacro MIMIC6-a {
   console /sixth create has been found/
   call {
      $mimic = sixth
      call talkMIMIC
   }
   timeout 5
}

automacro MIMIC6-b {
   console /our wounded scouts have reported/
   call {
      $mimic = sixth
      call talkMIMIC
   }
   timeout 5
}

#QUEST FINISH CHANGING CONFIG
automacro FINISHa {
   console /already did work for today/
   call changeCHAR
   timeout 5
}

automacro FINISHb {
   console /come back 20 hours/
   call changeCHAR
   timeout 5
}

#######MACROS###########

macro PORTNPC {
   $x = @random ("94","95","96","97","98")
   $y = @random ("60","61","62","63","64")
   do move alberta $x $y
   do talknpc 90 62 c r0 n 
}

macro talkMIMIC { 
   if ($mimic == first) goto mimic1
   if ($mimic == second) goto mimic2
   if ($mimic == third) goto mimic3
   if ($mimic == fourth) goto mimic4
   if ($mimic == fifth) goto mimic5
   if ($mimic == sixth) goto mimic6
   stop
   :mimic1
   $x = @random ("187","188","189","190","191")
   $y = @random ("164","165","166","167","168")
   do move $x $y
   do talknpc 188 173 c n
   stop
   :mimic2
   $x = @random ("224","225","226","227","228")
   $y = @random ("102","103","104","105","106")
   do move $x $y
   do talknpc 232 104 c n
   stop
   :mimic3
   $x = @random ("238","239","240","241","242")
   $y = @random ("88","89","90","91","92")
   do move $x $y
   do talknpc 246 87 c n 
   stop 
   :mimic4
   $x = @random ("238","239","240","241","242")
   $y = @random ("64","65","66","67","68")
   do move $x $y
   do talknpc 245 67 c n
   stop
   :mimic5
   $x = @random ("235","236","237","238","239")
   $y = @random ("40","41","42","43","44")
   do move $x $y
   do talknpc 243 43 c n
   stop
   :mimic6
   $x = @random ("114","115","116","117","118")
   $y = @random ("215","216","217","218","219")
   do move $x $y
   do talknpc 123 221 c n
   stop
}

macro retalkMIMIC {
   $num = $.lastMatch1 
   goto mimic
   stop
   :mimic 
   if ($num == [1]#:) goto retalk1
   if ($num == [2]#:) goto retalk2
   if ($num == [3]#:) goto retalk3
   if ($num == [4]#:) goto retalk4
   if ($num == [5]#:) goto retalk5
   stop
   :retalk1
   do talknpc 188 173 c n
   stop
   :retalk2
   do talknpc 232 104 c n
   stop
   :retalk3
   do talknpc 246 87 c n
   stop
   :retalk4
   do talknpc 245 67 c n
   stop
   :retalk5
   do talknpc 243 43 c n
   stop
   :retalk6
   do talknpc 123 221 c n
   stop
}

macro changeCHAR {
   $uname1 = yourusername
   $pword1 = yourpassword
   $slot1 = yourcharslot#

   $uname2 = yourusername
   $pword2 = yourpassword
   $slot2 = yourcharslot#

   $uname3 = yourusername
   $pword3 = yourpassword
   $slot3 = yourcharslot#

   $uname4 = yourusername
   $pword4 = yourpassword
   $slot4 = yourcharslot#

   $uname5 = yourusername
   $pword5 = yourpassword
   $slot5 = yourcharslot#

   goto char
   stop

   :char
   if (($uname1 == @config(username)) && ($pword1 == @config(password)) && ($slot1 == @config(char))) goto secondchar
   if (($uname2 == @config(username)) && ($pword2 == @config(password)) && ($slot2 == @config(char))) goto thirdchar
   if (($uname3 == @config(username)) && ($pword3 == @config(password)) && ($slot3 == @config(char))) goto fourthchar
   if (($uname4 == @config(username)) && ($pword4 == @config(password)) && ($slot4 == @config(char))) goto fifthchar
   if (($uname5 == @config(username)) && ($pword5 == @config(password)) && ($slot5 == @config(char))) goto firstchar 
   stop

   :secondchar
   do conf username $uname2
   do conf password $pword2
   do conf char $slot2
   do relog 5
   stop

   :thirdchar
   do conf username $uname3
   do conf password $pword3
   do conf char $slot3
   do relog 5
   stop

   :fourthchar
   do conf username $uname4
   do conf password $pword4
   do conf char $slot4
   do relog 5
   stop

   :fifthchar
   do conf username $uname5
   do conf password $pword5
   do conf char $slot5
   do relog 5
   stop

   :firstchar
   do conf username $uname1
   do conf password $pword1
   do conf char $slot1
   do relog 5
   stop
}

For those who play in servers w/o tele!

*disclaimer*
i didn't make this macro i just added monster names on it.
i got this macro from http://forums.openkore.com/viewtopic.php?f=15&t=8049
some of monster names repeat but it doesnt matter.
if you will use this macro to ur slave, remove # at the follow 1
Pros: better than relog method
i botted at gl_chyard and darklord never catch me, but my bot always see him and run from him SAFELY =)
use Ctrl + F(search) to find monsters that you want to remove from the list


be sure the mon_control its -1 0 0
in some cases it could be
Dark Lord 0 3 0 <<disconnect
or
Dark Lord 0 1 0<<teleport
better to use
Dark Lord -1 0 0<<avoid monster

thanks to madshark

Code:

#######################################
########Avoid Strong Monsters################
#######################################

automacro AvoidStrongMonsters {
#list of monsters to avoid:
monster Amon Ra, Archangeling, Baphomet, Bacsojin, Dark Illusion, Dark Lord, Detale, Doppelganger, Dracula, Drake, Eddga, Dark Snake Lord, Garm, Egnigem Cenia, Golden Thief Bug, Incantation Samurai, Lady Tany, Lord of Death, Maya, Maya Purple, Mistress, Moonlight, Mutant Dragon, Orc Hero, Orc Lord, Osiris, Pharaoh, Phreeoni, RSX-0806, Stormy Knight, Tao Gunka, Thanatos, Turtle General, Vesper, Howard Alt-Eisen, Seyren Windsor, Eremes Guile, Margaretha Sorin, Cecil Damon, Kathryne Keyron, Lord Knight Seyren, Assassin Cross Eremes, Whitesmith Howard, High Priest Margaretha, Sniper Cecil, High Wizard Kathryne, Morroc's Shadow Angel, Vocal, Morroc's Shadow Human, Abysmal Knight, Thanatos, Memory of Thanatos, Thanatos Despero, Despero of Thanatos, Thanatos Dolor, Dolor of Thanatos, Thanatos Maero, Maero of Thanatos, Thanatos Odium, Odium of Thanatos, Incantation Samurai, Samurai Specter, Incarnation of Morroc, Incarnation of Morroc, Sniper Shecil, Sniper Cecil, Bloody Knight, Knight Guardian, Knight of Abyss, Abysmal Knight, Knight of Windstorm, Stormy Knight, Lord Knight Seyren, Archdam, Archer Guardian, Acidus, Agav Alicel, Aliot, Amon Ra, Ancient Mimic, Ancient Mummy, Ancient Worm, Anolian, Anubis, Apocalypse, Armaia, Armeyer Dinze, Assassin Cross Eremes, Atroce, Aunoe, Bacsojin, White Lady, Baphomet, Banshee, Beelzebub, Bloody Butterfly, Bloody Murderer, Bow Guardian, Bow Master, Byorgue, Cat o' Nine Tails, Chimera, Chung E, Green Maiden, Civil Servant, Mao Guai, Dark Illusion, Dark Lord, Dark Priest, Dark Snake Lord, Evil Snake Lord, Deathword, Death Word, Deleter, Detale, Detarderous, Deviling, Diabolic, Dimik, Doppelganger, Dracula, Drake, Dullahan, Echio, Eddga, Entweihen Crothen, Eremes, Eremes Guile, Erend, Errende Ebecee, Executioner, Fallen Bishop, Fallen Bishop Hibram, Fanat, Ferus, Frus, Garden Watcher, Garden Keeper, Garm, Garm Baby, Gazeti, Gemini-S58, Gloom Under Night, Gremlin, Gryphon, Harpy, Harword, Howard Alt-Eisen, Hell Fly, Hellion Revenant, High Priest Magaleta, High Priest Margaretha, High Wizard Katrinn, High Wizard Kathryne, Hodremlin, Hydro, Hydrolancer, Ice Titan, Ifrit, Imp, Fire Imp, Samurai Specter, Incubus, Isilla, Kasa, Katrinn, Kathryne Keyron, Kavac, Kavach Icarus, Kiel, Kiehl, Knight Guardian, Lady Tanee, Lava Golem, Leib Olmai, Loli Ruri, Lord Knight Seyren, Lord of Death, Lord of the Dead, Magaleta, Margaretha Sorin, Majoruros, Marozka's Guard, Mavka, Maya, Maya Purple, Medusa, Mini Demon, Monemus, Mutant Dragon, Mutant Dragonoid, Mysteltainn, Naght Seiger, Necromancer, Nightmare Terror, Observation, Dame of Sentinel, Owl Baron, Owl Duke, Penomena, Pharaoh, Phendark, Piamette, Ragged Zombie, Rawrel, Laurell Weinder, Retribution, Baroness of Retribution, RSX 0806, RSX-0806, Salamander, Satan Morroc, Seyren, Seyren Windsor, Shecil,Cecil Damon, Shelter, Mistress of Shelter,, Shinobi, Skeggiold, Skogul, Sniper Shecil, Sniper Cecil, Soldier Guardian, Succubus, Sword Guardian, Sword Master, Thanatos, Memory of Thanatos, The Immortal Koshei, Thorn of Magic, Thorn of Purification, Thorn of Recovery, Thorny Skeleton, Tirfing, Ogretooth, Tristan III, Dead King, Ungoliant, Valkyrie, Valkyrie Randgris, Vanberk, Venatu, Vesper, Violy, Whitesmith Harword, Mastersmith Howard, Wicked Nymph, Evil Nymph, Wish Maiden, Wounded Morroc, Ygnizem, Egnigem Cenia, Zombie Slaughter

    timeout 3
    exclusive 1
    call caifora
}

macro caifora {
    $Move = 10

    $myPos = $.pos
    $myPosX = @arg ("$myPos", 1)
    $myPosY = @arg ("$myPos", 2)

    $monPos = $.lastMonsterPos
    $monPosX = @arg ("$monPos", 1)
    $monPosY = @arg ("$monPos", 2)


     if ($myPosX >= $monPosX) goto leste
     if ($myPosX < $monPosX) goto oeste

:leste
        if ($myPosY <= $monPosY) goto sudeste
        if ($myPosY > $monPosY) goto nordeste

     :sudeste
        do southeast $Move
        do move stop
        stop
        #do conf follow 1
   #pause 1
   #do reload config

     :nordeste
        do northeast $Move
        do move stop
        stop
        #do conf follow 1
   #pause 1
   #do reload config

:oeste
        if ($myPosY <= $monPosY) goto sudoeste
        if ($myPosY > $monPosY) goto noroeste

     :sudoeste
        do southwest $Move
        do move stop
        stop
        #do conf follow 1
   #pause 1
   #do reload config

     :noroeste
        do northwest $Move
        do move stop
        stop
        #do conf follow 1
   #pause 1
   #do reload config
}


P.S
if this macro is a double post at the macro section, sorry for that =p
im pretty sure it does contain much monster names =)

avoid MVP without teleportation

Code:
automacro evitarmvp {
#list of monsters to avoid:
    monster Amon Ra, Archangeling, Baphomet, Bacsojin, Dark Illusion, Dark Lord, Detale, Doppelganger, Dracula, Drake, Eddga, Dark Snake Lord, Garm, Egnigem Cenia, Golden Thief Bug, Incantation Samurai, Lady Tany, Lord of Death, Maya, Maya Purple, Mistress, Moonlight, Mutant Dragon, Orc Hero, Orc Lord, Osiris, Pharaoh, Phreeoni, RSX-0806, Stormy Knight, Tao Gunka, Thanatos, Turtle General, Vesper, Howard Alt-Eisen, Seyren Windsor, Eremes Guile, Margaretha Sorin, Cecil Damon, Kathryne Keyron, Lord Knight Seyren, Assassin Cross Eremes, Whitesmith Howard, High Priest Margaretha, Sniper Cecil, High Wizard Kathryne, Morroc's Shadow Angel, Vocal, Morroc's Shadow Human

    timeout 3
    exclusive 1
    call caifora
}

macro caifora {
    $Move = 10

    $myPos = $.pos
    $myPosX = @arg ("$myPos", 1)
    $myPosY = @arg ("$myPos", 2)

    $monPos = $.lastMonsterPos
    $monPosX = @arg ("$monPos", 1)
    $monPosY = @arg ("$monPos", 2)


     if ($myPosX >= $monPosX) goto leste
     if ($myPosX < $monPosX) goto oeste

:leste
        if ($myPosY <= $monPosY) goto sudeste
        if ($myPosY > $monPosY) goto nordeste

     :sudeste
        do southeast $Move
        do move stop
        stop
        #do conf follow 1

     :nordeste
        do northeast $Move
        do move stop
        stop
        #do conf follow 1

:oeste
        if ($myPosY <= $monPosY) goto sudoeste
        if ($myPosY > $monPosY) goto noroeste

     :sudoeste
        do southwest $Move
        do move stop
        stop
        #do conf follow 1

     :noroeste
        do northwest $Move
        do move stop
        stop
        #do conf follow 1
}

delete # infront of conf follow 1if use follow options

near player info

1. In Settings.PM ... just below the "# Data file folders." line... make it look like this...
Quote:
# Data file folders.
our @controlFolders;
our @tablesFolders;
our @pluginsFolders;
our @anything;
our %any;
our $i;
our $_name;
our $_guild;
our $_job;
our $_lvl;
our $_sex;
our $_dist;
our $_id;
our $_loc;
our @remove;
our $n;
# The registered data files.


2. Then... add this 4 subs after the sub getTablesFolders ..
Code:
sub setTry {
   ($_name, $_guild, $_job, $_lvl, $_sex, $_dist, $_id, $_loc) = @_;
   $i = 0 if $i eq "";
   %any;
   $any{$i}{name} = $_name;
   $any{$i}{guild} = $_guild;
   $any{$i}{job} = $_job;
   $any{$i}{lvl} = $_lvl;
   $any{$i}{sex} = $_sex;
   $any{$i}{dist} = $_dist;
   $any{$i}{id} = $_id;
   $any{$i}{loc} = $_loc;
   push(@anything, \%any);
   $i++;
}
sub setUndef {
   undef @anything;
   undef $i;
}
sub getTry {
   return @anything;
}
sub removeTry {
   undef @remove;
   ($_name) = shift;

   if (@{\@anything} > 0 && defined $_name) {
      $i = 0;
      $n = 0;
      foreach my $any1 (@anything) {
         if ($any1->{$n}{name} eq $_name) {
            $n++;
            next;
         }
         %any;
         $any{$i}{name} = $any1->{$n}{name};
         $any{$i}{guild} = $any1->{$n}{guild};
         $any{$i}{job} = $any1->{$n}{job};
         $any{$i}{lvl} = $any1->{$n}{lvl};
         $any{$i}{sex} = $any1->{$n}{sex};
         $any{$i}{dist} = $any1->{$n}{dist};
         $any{$i}{id} = $any1->{$n}{id};
         $any{$i}{loc} = $any1->{$n}{loc};
         push(@remove, \%any);
         $i++;
         $n++;
      }
      undef @anything;
      @anything = @remove;
   } 
}

In config.txt ... create a new line for filtering purpose
Quote:
guildList guild1,guild2,guild3
PlayersDist 7

In Macro:

Code:
macro player {
log Scanning Players Info...
do eval Settings::setUndef();for (my $_i = 0; $_i < @playersID; $_i++) {my $_player = $::players{$::playersID[$_i]};next if $_player eq "";$_guild = ($_player->{guild})?$_player->{guild}{name}:'none';$_name = ($_player->{'name'})?$_player->{'name'}:"Unknown";$_job = $::jobs_lut{$_player->{jobID}};$_lvl = $_player->{'lv'};$_sex = $::sex_lut{$_player->{'sex'}};$_dist = sprintf("%.1f", distance($::char->{pos_to}, $_player->{pos_to}));$_id = $_player->{'binID'};$_loc = "$_player->{pos_to}{x}" . " $_player->{pos_to}{y}";Settings::setTry($_name, $_guild, $_job, $_lvl, $_sex, $_dist, $_id, $_loc)}
pause 2
log Done!!
}

macro print {
log Printing Players Info
do eval my $_i = 0;my @print = Settings::getTry();foreach (@print) {next if ($_ eq "");$_g = $_->{$_i}{guild}; $_n = $_->{$_i}{name};$_j = $_->{$_i}{job};$_l = $_->{$_i}{lvl};$_s = $_->{$_i}{sex};$_d = $_->{$_i}{dist};$_id = $_->{$_i}{id};$_loc = $_->{$_i}{loc};message "$_id, $_n, $_g, $_l, $_s, $_j, $_d, $_loc\n", "macro";$_i++}
}

macro filter {
log Filtering the Players Info
do eval my $_i = 0;my @print = Settings::getTry();foreach (@print) {$_g = $_->{$_i}{guild};$_n = $_->{$_i}{name};if ($_ eq "" || !existsInList($::config{guildList}, $_g) || $_->{$_i}{dist} > $::config{PlayersDist} || $_g eq "none" || $_n eq "Unknown") {Settings::removeTry("$_n");next} else {$_j = $_->{$_i}{job};$_l = $_->{$_i}{lvl};$_s = $_->{$_i}{sex};$_d = $_->{$_i}{dist};$_id = $_->{$_i}{id};$_loc = $_->{$_i}{loc};message "$_id, $_n, $_g, $_l, $_s, $_j, $_d, $_loc\n", "macro";$_i++}}
}

macro filter2 {
log Filtering the Players Info and take out the 1st matching infos
$name = none
$id = none
do eval my $_i = 0;my @print = Settings::getTry();foreach (@print) {$_g = $_->{$_i}{guild};$_n = $_->{$_i}{name};if ($_ eq "" || !existsInList($::config{guildList}, $_g) || $_->{$_i}{dist} > $::config{PlayersDist} || $_g eq "none" || $_n eq "Unknown") {Settings::removeTry("$_n");next} else {$::Macro::Data::varStack{job} = $_->{$_i}{job};$::Macro::Data::varStack{lvl} = $_->{$_i}{lvl};$::Macro::Data::varStack{sex} = $_->{$_i}{sex};$::Macro::Data::varStack{dist} = $_->{$_i}{dist};$::Macro::Data::varStack{id} = $_->{$_i}{id};$::Macro::Data::varStack{loc} = $_->{$_i}{loc};$::Macro::Data::varStack{guild} = $_g;$::Macro::Data::varStack{name} = $_n;last}}

if ($name = none || $id = none) stop
log $name ($id) [$guild] $sex $job $lvl $dist ($loc)
log Do something with $name ($id)
log After that remove it from the info list
call remove
}

macro remove {
#$removeName shouldn't be blank and must be player's name
$removeName = $name
log Removing Player's Name ($removeName)
do eval Settings::removeTry("$removeName")
}

Quote:
1. macro player = collecting infos.
2. macro print = printing the current infos.
3. macro filter = filtering the current infos.
4. macro filter2 = filtering + setting the macro var. Then remove the info from the info list.
5. macro remove = remove the player's name and its infos from the current info list.

How to use?
  • a. Use 1, 2, 3 and 2 again = You'll see all the players info 1st, then you'll see the filter result.
  • b. Use 1, 2, 4 (repeat the 4 untill nothing happened) = Ermmm... better you try it 1st coz I dont know how to tell you ^^
Utilities.PM - Enable the range numbers in (?:auto|)macro
Code:
--- https://openkore.svn.sourceforge.net/svnroot/openkore/plugins/macro/trunk/Macro/Utilities.pm   Wed May 20 12:10:04 2009
+++ C:/.../plugins/Macro/Utilities.pm   My working copy
@@ -64,6 +64,28 @@
      return 0
   }

+   if ($a =~ /^\s*(-?[\d.]+)\s*\.{2}\s*(-?[\d.]+)\s*$/) {
+      my ($a1, $a2) = ($1, $2);
+      if ($b =~ /^-?[\d.]+$/) {
+         if ($cond eq "!=") {return 1 unless $a1 <= $b && $b <= $a2}
+         if ($cond eq "=" || $cond eq "==" || $cond eq "=~" || $cond eq "~") {
+            return 1 if $a1 <= $b && $b <= $a2
+         }
+      }
+      return 0
+   }
+
+   if ($b =~ /^\s*(-?[\d.]+)\s*\.{2}\s*(-?[\d.]+)\s*$/) {
+      my ($b1, $b2) = ($1, $2);
+      if ($a =~ /^-?[\d.]+$/) {
+         if ($cond eq "!=") {return 1 unless $b1 <= $a && $a <= $b2}
+         if ($cond eq "=" || $cond eq "==" || $cond eq "=~" || $cond eq "~") {
+            return 1 if $b1 <= $a && $a <= $b2
+         }
+      }
+      return 0
+   }
+
   if ($a =~ /^-?[\d.]+$/ && $b =~ /^-?[\d.]+$/) {
      if (($cond eq "=" || $cond eq "==") && $a == $b) {return 1}
      if ($cond eq ">=" && $a >= $b) {return 1}
@@ -80,6 +102,7 @@
      $a = lc($a);
      foreach my $e (split(/,/, $b)) {return 1 if $a eq lc($e)}
   }
+
   return 0
}

@@ -396,4 +419,4 @@
   }
}

-1;
\ No newline at end of file
+1;



Script.PM - Vision: Perl-A-Like Macro Script
Code:
--- https://openkore.svn.sourceforge.net/svnroot/openkore/plugins/macro/trunk/Macro/Script.pm   Wed May 20 12:09:38 2009
+++ C:/.../plugins/Macro/Script.pm   My working copy
@@ -1,3 +1,4 @@
+# ezza's Latest Patch: 04/06/2009 @ 12:00pm
# $Id: Script.pm 5939 2007-08-29 12:09:28Z arachnophobia $
package Macro::Script;

@@ -13,37 +14,49 @@
use Macro::Parser qw(parseCmd);
use Macro::Utilities qw(cmpr);
use Macro::Automacro qw(releaseAM lockAM);
-use Log qw(message);
+use Log qw(message warning);

our ($rev) = q$Revision: 5939 $ =~ /(\d+)/;

# constructor
sub new {
-   my ($class, $name, $repeat) = @_;
+   my ($class, $name, $repeat, $lastname, $lastline) = @_;
   $repeat = 0 unless ($repeat && $repeat =~ /^\d+$/);
   return unless defined $macro{$name};
   my $self = {
-      name => $name,
-      registered => 0,
-      submacro => 0,
-      macro_delay => $timeout{macro_delay}{timeout},
-      timeout => 0,
-      time => time,
-      finished => 0,
-      overrideAI => 0,
-      line => 0,
-      label => {scanLabels($macro{$name})},
-      repeat => $repeat,
-      subcall => undef,
-      error => undef,
-      orphan => $::config{macro_orphans},
-      interruptible => 1,
-      macro_block => 0
+         name => $name,
+         lastname => undef,
+         registered => 0,
+         submacro => 0,
+         macro_delay => $timeout{macro_delay}{timeout},
+         timeout => 0,
+         mainline_delay => undef,
+         subline_delay => undef,
+         result => undef,
+         time => time,
+         finished => 0,
+         overrideAI => 0,
+         line => 0,
+         lastline => undef,
+         label => {scanLabels($macro{$name})},
+         repeat => $repeat,
+         subcall => undef,
+         error => undef,
+         orphan => $::config{macro_orphans},
+         interruptible => 1,
+         macro_block => 0
+
   };
+   if (defined $lastname && defined $lastline) {
+      $self->{lastname} = $lastname;
+      $self->{lastline} = $lastline;
+      $self->{interruptible} = 0;
+   }
   bless ($self, $class);
   return $self
}

+
# destructor
sub DESTROY {
   AI::clear('macro') if (AI::inQueue('macro') && !$_[0]->{submacro})
@@ -164,37 +177,36 @@
      $self->{error} = $self->{subcall}->{error};
      return
   }
+   if (defined $self->{mainline_delay} && defined $self->{subline_delay}) {$self->{line} = $self->{mainline_delay}}
   my $line = ${$macro{$self->{name}}}[$self->{line}];
   if (!defined $line) {
-      if ($self->{repeat} > 1) {
-         $self->{repeat}--;
-         $self->{line} = 0
-      } else {
-         $self->{finished} = 1
+      if (defined $self->{lastname} && defined $self->{lastline}) {
+         $self->{line} = $self->{lastline} + 1;
+         $self->{name} = $self->{lastname};
+         $line = ${$macro{$self->{name}}}[$self->{line}];
+         ($self->{lastline}, $self->{lastname}) = undef
      }
-      return ""
+      else {
+         if ($self->{repeat} > 1) {$self->{repeat}--; $self->{line} = 0}
+         else {$self->{finished} = 1}
+         return ""
+      }
   }
-

   my $errtpl = "error in ".$self->{line};
   ##########################################
   # jump to label: goto label
   if ($line =~ /^goto\s/) {
      my ($tmp) = $line =~ /^goto\s+([a-zA-Z][a-zA-Z\d]*)/;
-      if (exists $self->{label}->{$tmp}) {
-         $self->{line} = $self->{label}->{$tmp}
-      } else {
-         $self->{error} = "$errtpl: cannot find label $tmp"
-      }
+      if (exists $self->{label}->{$tmp}) {$self->{line} = $self->{label}->{$tmp}}
+      else {$self->{error} = "$errtpl: cannot find label $tmp"}
      $self->{timeout} = 0
   ##########################################
   # declare block ending: end label
   } elsif ($line =~ /^end\s/) {
      my ($tmp) = $line =~ /^end\s+(.*)/;
-      if (exists $self->{label}->{$tmp}) {
-         $self->{line} = $self->{label}->{$tmp}
-      } else {
-         $self->{error} = "$errtpl: cannot find block start for $tmp"
-      }
+      if (exists $self->{label}->{$tmp}) {$self->{line} = $self->{label}->{$tmp}}
+      else {$self->{error} = "$errtpl: cannot find block start for $tmp"}
      $self->{timeout} = 0
   ##########################################
   # macro block: begin
@@ -209,112 +221,102 @@
      $self->{line}++
   ##########################################
   # if statement: if (foo = bar) goto label?
+   # Unlimited If Statement by: ezza @ http://forums.openkore.com/
   } elsif ($line =~ /^if\s/) {
-      my ($first, $cond, $last, $then) = $line =~ /^if\s+\(\s*"?(.*?)"?\s+([<>=!~]+?)\s+"?(.*?)"?\s*\)\s+(.*)/;
-      if (!defined $first || !defined $cond || !defined $last || !defined $then || $then !~ /^(?:goto\s|stop)/) {
-         $self->{error} = "$errtpl: syntax error in if statement"
-      } else {
-         my $pfirst = parseCmd($first); my $plast = parseCmd($last);
-         unless (defined $pfirst && defined $plast) {
-            $self->{error} = "$errtpl: either '$first' or '$last' has failed"
-         } elsif (cmpr($pfirst, $cond, $plast)) {
-            if ($then =~ /^goto\s/) {
-               my ($tmp) = $then =~ /^goto\s+([a-zA-Z][a-zA-Z\d]*)$/;
-               if (exists $self->{label}->{$tmp}) {
-                  $self->{line} = $self->{label}->{$tmp}
-               } else {
-                  $self->{error} = "$errtpl: cannot find label $tmp"
-               }
-            } elsif ($then eq "stop") {
-               $self->{finished} = 1
-            }
-         } else {
-            $self->{line}++
-         }
-      }
+      my ($text, $then) = $line =~ /^if\s\(\s*(.*)\s*\)\s+(goto\s+.*|call\s+.*|stop)\s*/;
+
+      # The main trick is parse all the @special keyword and vars 1st,
+      $text = parseCmd($text);
+      my $savetxt = particle($text, $self, $errtpl);
+      if (multi($savetxt, $self, $errtpl)) {newThen($then, $self, $errtpl)}
+
+      $self->{line}++;
      $self->{timeout} = 0
+
   ##########################################
   # while statement: while (foo <= bar) as label
   } elsif ($line =~ /^while\s/) {
      my ($first, $cond, $last, $label) = $line =~ /^while\s+\(\s*"?(.*?)"?\s+([<>=!]+?)\s+"?(.*?)"?\s*\)\s+as\s+(.*)/;
-      if (!defined $first || !defined $cond || !defined $last || !defined $label) {
-         $self->{error} = "$errtpl: syntax error in while statement"
-      } else {
+      if (!defined $first || !defined $cond || !defined $last || !defined $label) {$self->{error} = "$errtpl: syntax error in while statement"}
+      else {
         my $pfirst = parseCmd($first); my $plast = parseCmd($last);
-         unless (defined $pfirst && defined $plast) {
-            $self->{error} = "$errtpl: either '$first' or '$last' has failed"
-         } elsif (!cmpr($pfirst, $cond, $plast)) {
-            $self->{line} = $self->{label}->{"end ".$label}
-         }
+         unless (defined $pfirst && defined $plast) {$self->{error} = "$errtpl: either '$first' or '$last' has failed"}
+         elsif (!cmpr($pfirst, $cond, $plast)) {$self->{line} = $self->{label}->{"end ".$label}}
         $self->{line}++
      }
      $self->{timeout} = 0
   ##########################################
   # pop value from variable: $var = [$list]
   } elsif ($line =~ /^\$[a-z][a-z\d]*\s+=\s+\[\s*\$[a-z][a-z\d]*\s*\]$/i) {
-      my ($var, $list) = $line =~ /^\$([a-z][a-z\d]*?)\s+=\s+\[\s*\$([a-z][a-z\d]*?)\s*\]$/i;
-      my $listitems = ($varStack{$list} or "");
-      my $val;
-      if (($val) = $listitems =~ /^(.*?)(?:,|$)/) {
-         $listitems =~ s/^(?:.*?)(?:,|$)//;
-         $varStack{$list} = $listitems
-      } else {
-         $val = $listitems
+      if ($line =~ /;/) {run_sublines($line, $self)}
+      else {
+         my ($var, $list) = $line =~ /^\$([a-z][a-z\d]*?)\s+=\s+\[\s*\$([a-z][a-z\d]*?)\s*\]$/i;
+         my $listitems = ($varStack{$list} or "");
+         my $val;
+         if (($val) = $listitems =~ /^(.*?)(?:,|$)/) {
+            $listitems =~ s/^(?:.*?)(?:,|$)//;
+            $varStack{$list} = $listitems
+         }
+         else {$val = $listitems}
+         $varStack{$var} = $val;
      }
-      $varStack{$var} = $val;
      $self->{line}++;
-      $self->{timeout} = 0;
+      $self->{timeout} = 0 unless defined $self->{mainline_delay} && defined $self->{subline_delay};
+      return $self->{result} if $self->{result}
   ##########################################
   # set variable: $variable = value
   } elsif ($line =~ /^\$[a-z]/i) {
      my ($var, $val);
-      if (($var, $val) = $line =~ /^\$([a-z][a-z\d]*?)\s+=\s+(.*)/i) {
-         my $pval = parseCmd($val);
-         if (defined $pval) {$varStack{$var} = $pval}
-         else {$self->{error} = "$errtpl: $val failed"}
-      } elsif (($var, $val) = $line =~ /^\$([a-z][a-z\d]*?)([+-]{2})$/i) {
-         if ($val eq '++') {
-            $varStack{$var} = ($varStack{$var} or 0)+1
-         } else {
-            $varStack{$var} = ($varStack{$var} or 0)-1
+      if ($line =~ /;/) {run_sublines($line, $self)}
+      else {
+         if (($var, $val) = $line =~ /^\$([a-z][a-z\d]*?)\s+=\s+(.*)/i) {
+            my $pval = parseCmd($val);
+            if (defined $pval) {
+               if ($pval =~ /^\s*(?:undef|unset)\s*$/i && exists $varStack{$var}) {undef $varStack{$var}}
+               else {$varStack{$var} = $pval}
+            }
+            else {$self->{error} = "$errtpl: $val failed"}
         }
-      } else {
-         $self->{error} = "$errtpl: unrecognized assignment"
+         elsif (($var, $val) = $line =~ /^\$([a-z][a-z\d]*?)([+-]{2})$/i) {
+            if ($val eq '++') {$varStack{$var} = ($varStack{$var} or 0)+1}
+            else {$varStack{$var} = ($varStack{$var} or 0)-1}
+         }
+         else {$self->{error} = "$errtpl: unrecognized assignment"}
      }
      $self->{line}++;
-      $self->{timeout} = 0
+      $self->{timeout} = 0 unless defined $self->{mainline_delay} && defined $self->{subline_delay};
+      return $self->{result} if $self->{result}
   ##########################################
   # set doublevar: ${$variable} = value
   } elsif ($line =~ /^\$\{\$[.a-z]/i) {
      my ($dvar, $val);
-      if (($dvar, $val) = $line =~ /^\$\{\$([.a-z][a-z\d]*?)\}\s+=\s+(.*)/i) {
-         my $var = $varStack{$dvar};
-         unless (defined $var) {
-            $self->{error} = "$errtpl: $dvar not defined"
-         } else {
-            my $pval = parseCmd($val);
-            unless (defined $pval) {
-               $self->{error} = "$errtpl: $val failed"
-            } else {
-               $varStack{"#$var"} = parseCmd($val)
+      if ($line =~ /;/) {run_sublines($line, $self)}
+      else {
+         if (($dvar, $val) = $line =~ /^\$\{\$([.a-z][a-z\d]*?)\}\s+=\s+(.*)/i) {
+            my $var = $varStack{$dvar};
+            unless (defined $var) {$self->{error} = "$errtpl: $dvar not defined"}
+            else {
+               my $pval = parseCmd($val);
+               unless (defined $pval) {$self->{error} = "$errtpl: $val failed"}
+               else {
+                  if ($pval =~ /^\s*(?:undef|unset)\s*$/i) {undef $varStack{"#$var"}}
+                  else {$varStack{"#$var"} = $pval}
+               }
            }
         }
-      } elsif (($dvar, $val) = $line =~ /^\$\{\$([.a-z][a-z\d]*?)\}([+-]{2})$/i) {
-         my $var = $varStack{$dvar};
-         unless (defined $var) {
-            $self->{error} = "$errtpl: $dvar undefined"
-         } else {
-            if ($val eq '++') {
-               $varStack{"#$var"} = ($varStack{"#$var"} or 0)+1
-            } else {
-               $varStack{"#$var"} = ($varStack{"#$var"} or 0)-1
+         elsif (($dvar, $val) = $line =~ /^\$\{\$([.a-z][a-z\d]*?)\}([+-]{2})$/i) {
+            my $var = $varStack{$dvar};
+            unless (defined $var) {$self->{error} = "$errtpl: $dvar undefined"}
+            else {
+               if ($val eq '++') {$varStack{"#$var"} = ($varStack{"#$var"} or 0)+1}
+               else {$varStack{"#$var"} = ($varStack{"#$var"} or 0)-1}
            }
         }
-      } else {
-         $self->{error} = "$errtpl: unrecognized assignment."
+         else {$self->{error} = "$errtpl: unrecognized assignment."}
      }
      $self->{line}++;
-      $self->{timeout} = 0
+      $self->{timeout} = 0 unless defined $self->{mainline_delay} && defined $self->{subline_delay};
+      return $self->{result} if $self->{result}
   ##########################################
   # label definition: :label
   } elsif ($line =~ /^:/) {
@@ -323,59 +325,60 @@
   ##########################################
   # returns command: do whatever
   } elsif ($line =~ /^do\s/) {
-      my ($tmp) = $line =~ /^do\s+(.*)/;
-      if ($tmp =~ /^macro\s+/) {
-         my ($arg) = $tmp =~ /^macro\s+(.*)/;
-         if ($arg =~ /^reset/) {
-            $self->{error} = "$errtpl: use 'release' instead of 'macro reset'"
-         } elsif ($arg eq 'pause' || $arg eq 'resume') {
-            $self->{error} = "$errtpl: do not use 'macro pause' or 'macro resume' within a macro"
-         } elsif ($arg =~ /^set\s/) {
-            $self->{error} = "$errtpl: do not use 'macro set'. Use \$foo = bar"
-         } elsif ($arg eq 'stop') {
-            $self->{error} = "$errtpl: use 'stop' instead"
-         } elsif ($arg !~ /^(?:list|status)$/) {
-            $self->{error} = "$errtpl: use 'call $arg' instead of 'macro $arg'"
+      if ($line =~ /;/ && $line =~ /^do eval/ eq "") {
+         run_sublines($line, $self);
+         unless (defined $self->{mainline_delay} && defined $self->{subline_delay}) {$self->{timeout} = $self->{macro_delay}; $self->{line}++}
+         if ($self->{result}) {return $self->{result}}
+      }
+      else {
+         my ($tmp) = $line =~ /^do\s+(.*)/;
+         if ($tmp =~ /^macro\s+/) {
+            my ($arg) = $tmp =~ /^macro\s+(.*)/;
+            if ($arg =~ /^reset/) {$self->{error} = "$errtpl: use 'release' instead of 'macro reset'"}
+            elsif ($arg eq 'pause' || $arg eq 'resume') {$self->{error} = "$errtpl: do not use 'macro pause' or 'macro resume' within a macro"}
+            elsif ($arg =~ /^set\s/) {$self->{error} = "$errtpl: do not use 'macro set'. Use \$foo = bar"}
+            elsif ($arg eq 'stop') {$self->{error} = "$errtpl: use 'stop' instead"}
+            elsif ($arg !~ /^(?:list|status)$/) {$self->{error} = "$errtpl: use 'call $arg' instead of 'macro $arg'"}
         }
-      } elsif ($tmp =~ /^ai\s+clear$/) {
-         $self->{error} = "$errtpl: do not mess around with ai in macros"
+         elsif ($tmp =~ /^ai\s+clear$/) {$self->{error} = "$errtpl: do not mess around with ai in macros"}
+         return if defined $self->{error};
+         my $result = parseCmd($tmp);
+         unless (defined $result) {$self->{error} = "$errtpl: command $tmp failed";return}
+         $self->{timeout} = $self->{macro_delay};
+         $self->{line}++;
+         return $result
      }
-      return if defined $self->{error};
-      my $result = parseCmd($tmp);
-      unless (defined $result) {
-         $self->{error} = "$errtpl: command $tmp failed";
-         return
-      }
-      $self->{line}++;
-      $self->{timeout} = $self->{macro_delay};
-      return $result
   ##########################################
   # log command
   } elsif ($line =~ /^log\s+/) {
-      my ($tmp) = $line =~ /^log\s+(.*)/;
-      my $result = parseCmd($tmp);
-      unless (defined $result) {
-         $self->{error} = "$errtpl: $tmp failed"
-      } else {
-         message "[macro][log] $result\n", "macro";
+      if ($line =~ /;/) {run_sublines($line, $self)}
+      else {
+         my ($tmp) = $line =~ /^log\s+(.*)/;
+         my $result = parseCmd($tmp);
+         unless (defined $result) {$self->{error} = "$errtpl: $tmp failed"}
+         else {message "[macro log] $result\n", "macro";}
      }
      $self->{line}++;
-      $self->{timeout} = $self->{macro_delay}
+      $self->{timeout} = $self->{macro_delay} unless defined $self->{mainline_delay} && defined $self->{subline_delay};
+      return $self->{result} if $self->{result}
   ##########################################
   # pause command
   } elsif ($line =~ /^pause/) {
-      my ($tmp) = $line =~ /^pause\s*(.*)/;
-      if (defined $tmp) {
-         my $result = parseCmd($tmp);
-         unless (defined $result) {
-            $self->{error} = "$errtpl: $tmp failed"
-         } else {
-            $self->{timeout} = $result
+      if ($line =~ /;/) {
+         run_sublines($line, $self);
+         $self->{timeout} = $self->{macro_delay} unless defined $self->{mainline_delay} && defined $self->{subline_delay}
+      }
+      else {
+         my ($tmp) = $line =~ /^pause\s*(.*)/;
+         if (defined $tmp) {
+            my $result = parseCmd($tmp);
+            unless (defined $result) {$self->{error} = "$errtpl: $tmp failed"}
+            else {$self->{timeout} = $result}
         }
-      } else {
-         $self->{timeout} = $self->{macro_delay}
+         else {$self->{timeout} = $self->{macro_delay}}
      }
-      $self->{line}++
+      $self->{line}++;
+      return $self->{result} if $self->{result}
   ##########################################
   # stop command
   } elsif ($line eq "stop") {
@@ -383,21 +386,27 @@
   ##########################################
   # release command
   } elsif ($line =~ /^release\s+/) {
-      my ($tmp) = $line =~ /^release\s+(.*)/;
-      if (!releaseAM(parseCmd($tmp))) {
-         $self->{error} = "$errtpl: releasing $tmp failed"
+      if ($line =~ /;/) {run_sublines($line, $self)}
+      else {
+         my ($tmp) = $line =~ /^release\s+(.*)/;
+         if (!releaseAM(parseCmd($tmp))) {
+            $self->{error} = "$errtpl: releasing $tmp failed"
+         }
      }
      $self->{line}++;
-      $self->{timeout} = 0
+      $self->{timeout} = 0 unless defined $self->{mainline_delay} && defined $self->{subline_delay};
+      return $self->{result} if $self->{result}
   ##########################################
   # lock command
   } elsif ($line =~ /^lock\s+/) {
-      my ($tmp) = $line =~ /^lock\s+(.*)/;
-      if (!lockAM(parseCmd($tmp))) {
-         $self->{error} = "$errtpl: locking $tmp failed"
+      if ($line =~ /;/) {run_sublines($line, $self)}
+      else {
+         my ($tmp) = $line =~ /^lock\s+(.*)/;
+         if (!lockAM(parseCmd($tmp))) {$self->{error} = "$errtpl: locking $tmp failed"}
      }
      $self->{line}++;
-      $self->{timeout} = 0
+      $self->{timeout} = 0 unless defined $self->{mainline_delay} && defined $self->{subline_delay};
+      return $self->{result} if $self->{result}
   ##########################################
   # call command
   } elsif ($line =~ /^call\s+/) {
@@ -405,43 +414,426 @@
      if ($tmp =~ /\s/) {
         my ($name, $times) = $tmp =~ /(.*?)\s+(.*)/;
         my $ptimes = parseCmd($times);
-         if (defined $ptimes) {
-            $self->{subcall} = new Macro::Script($name, $ptimes)
-         }
-      } else {
-         $self->{subcall} = new Macro::Script($tmp)
+         if (defined $ptimes && $ptimes =~ /\d+/) {$self->{subcall} = new Macro::Script($name, $ptimes)}
+         else {$self->{subcall} = new Macro::Script($name)}
      }
-      unless (defined $self->{subcall}) {
-         $self->{error} = "$errtpl: failed to call script"
-      } else {
+      else {$self->{subcall} = new Macro::Script($tmp)}
+      unless (defined $self->{subcall}) {$self->{error} = "$errtpl: failed to call script"}
+      else {
         $self->{subcall}->regSubmacro;
         $self->{timeout} = $self->{macro_delay}
      }
   ##########################################
   # set command
   } elsif ($line =~ /^set\s+/) {
-      my ($var, $val) = $line =~ /^set\s+(\w+)\s+(.*)$/;
-      if ($var eq 'macro_delay' && $val =~ /^[\d\.]*\d+$/) {
-         $self->{macro_delay} = $val
-      } elsif ($var eq 'repeat' && $val =~ /^\d+$/) {
-         $self->{repeat} = $val
-      } elsif ($var eq 'overrideAI' && $val =~ /^[01]$/) {
-         $self->{overrideAI} = $val
-      } elsif ($var eq 'exclusive' && $val =~ /^[01]$/) {
-         $self->{interruptible} = $val?0:1
-      } elsif ($var eq 'orphan' && $val =~ /^(?:terminate|reregister(?:_safe)?)$/) {
-         $self->{orphan} = $val
-      } else {
-         $self->{error} = "$errtpl: unrecognized key or wrong value"
+      if ($line =~ /;/) {run_sublines($line, $self)}
+      else {
+         my ($var, $val) = $line =~ /^set\s+(\w+)\s+(.*)$/;
+         if ($var eq 'macro_delay' && $val =~ /^[\d\.]*\d+$/) {
+            $self->{macro_delay} = $val
+         } elsif ($var eq 'repeat' && $val =~ /^\d+$/) {
+            $self->{repeat} = $val
+         } elsif ($var eq 'overrideAI' && $val =~ /^[01]$/) {
+            $self->{overrideAI} = $val
+         } elsif ($var eq 'exclusive' && $val =~ /^[01]$/) {
+            $self->{interruptible} = $val?0:1
+         } elsif ($var eq 'orphan' && $val =~ /^(?:terminate|reregister(?:_safe)?)$/) {
+            $self->{orphan} = $val
+         } else {
+            $self->{error} = "$errtpl: unrecognized key or wrong value"
+         }
      }
      $self->{line}++;
-      $self->{timeout} = 0
+      $self->{timeout} = 0 unless defined $self->{mainline_delay} && defined $self->{subline_delay};
+      return $self->{result} if $self->{result}
   ##########################################
+   # sub-routine command, still figuring out how to include unclever/fail sub-routine into the error msg
+   } elsif ($line =~ /^(?:\w+)\s*\(.*?\)/) {
+      if ($line =~ /;/) {run_sublines($line, $self)}
+      else {
+         my ($sub) = $line =~ /^(\w+)\s*\(.*?\)$/;
+         my $sub_error = 1;
+         foreach my $e (@macro_block) {if ($e eq $sub) {$sub_error = 0; parseCmd($line)}}
+         $self->{error} = "$errtpl: sub-routine $sub in --> $line <-- not found!!!" if $sub_error;
+      }
+      $self->{line}++;
+      $self->{timeout} = 0 unless defined $self->{mainline_delay} && defined $self->{subline_delay};
+      return $self->{result} if $self->{result}
+   ##########################################
   # unrecognized line
   } else {
      $self->{error} = "$errtpl: syntax error"
   }

   if (defined $self->{error}) {return} else {return ""}
}

+
+sub run_sublines {
+   my ($real_line, $self) = @_;
+   my ($i, $real_num, @sub_line) = (0, $self->{line}, undef);
+   my @split = split(/\s*;\s*/, $real_line);
+   my ($dvar, $var, $val, $list);

+   foreach my $e (@split) {
+      next if $e eq "";
+      if (defined $self->{subline_delay} && $i < $self->{subline_delay}) {$i++; next}
+      if (defined $self->{subline_delay} && $i == $self->{subline_delay}) {
+         $self->{timeout} = 0;
+         ($self->{mainline_delay}, $self->{subline_delay}, $self->{result}) = undef;
+         $i++; next
+      }
+    
+      ##########################################
+      # pop value from variable: $var = [$list]
+      if ($e =~ /^\$[a-z][a-z\d]*\s+=\s+\[\s*\$[a-z][a-z\d]*\s*\]$/i) {
+         ($var, $list) = $e =~ /^\$([a-z][a-z\d]*?)\s+=\s+\[\s*\$([a-z][a-z\d]*?)\s*\]$/i;
+         my $listitems = ($varStack{$list} or "");
+         if (($val) = $listitems =~ /^(.*?)(?:,|$)/) {
+            $listitems =~ s/^(?:.*?)(?:,|$)//;
+            $varStack{$list} = $listitems
+         }
+         else {$val = $listitems}
+         $varStack{$var} = $val;
+         $i++; next
+          
+      # set variable: $variable = value
+      } elsif ($e =~ /^\$[a-z]/i) {
+         if (($var, $val) = $e =~ /^\$([a-z][a-z\d]*?)\s+=\s+(.*)/i) {
+            my $pval = parseCmd($val);
+            if (defined $pval) {
+               if ($pval =~ /^\s*(?:undef|unset)\s*$/i && exists $varStack{$var}) {undef $varStack{$var}}
+               else {$varStack{$var} = $pval}
+            }
+            else {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: $e failed"; last}
+         }
+         elsif (($var, $val) = $e =~ /^\$([a-z][a-z\d]*?)([+-]{2})$/i) {
+            if ($val eq '++') {$varStack{$var} = ($varStack{$var} or 0)+1} else {$varStack{$var} = ($varStack{$var} or 0)-1}
+         }
+         else {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: unrecognized assignment in ($e)"; last}
+         $i++; next
+          
+      # set doublevar: ${$variable} = value
+      } elsif ($e =~ /^\$\{\$[.a-z]/i) {
+         if (($dvar, $val) = $e =~ /^\$\{\$([.a-z][a-z\d]*?)\}\s+=\s+(.*)/i) {
+            $var = $varStack{$dvar};
+            unless (defined $var) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: $dvar not defined in ($e)"; last}
+            else {
+               my $pval = parseCmd($val);
+               unless (defined $pval) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: $e failed"; last}
+               else {
+                  if ($pval =~ /^\s*(?:undef|unset)\s*$/i) {undef $varStack{"#$var"}}
+                  else {$varStack{"#$var"} = $pval}
+               }
+            }
+         }
+         elsif (($dvar, $val) = $e =~ /^\$\{\$([.a-z][a-z\d]*?)\}([+-]{2})$/i) {
+            $var = $varStack{$dvar};
+            unless (defined $var) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: undefined $dvar in ($e)"; last}
+            else {if ($val eq '++') {$varStack{"#$var"} = ($varStack{"#$var"} or 0)+1} else {$varStack{"#$var"} = ($varStack{"#$var"} or 0)-1}}
+            $i++; next
+         }
+         else {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: unrecognized assignment in ($e)"; last}
+         $i++; next
+          
+      # stop command
+      } elsif ($e eq "stop") {
+         $self->{finished} = 1; last
+    
+      # set command
+      } elsif (($var, $val) = $e =~ /^set\s+(\w+)\s+(.*)$/) {
+         if ($var eq 'macro_delay' && $val =~ /^[\d\.]*\d+$/) {$self->{macro_delay} = $val}
+         elsif ($var eq 'repeat' && $val =~ /^\d+$/) {$self->{repeat} = $val}
+         elsif ($var eq 'overrideAI' && $val =~ /^[01]$/) {$self->{overrideAI} = $val}
+         elsif ($var eq 'exclusive' && $val =~ /^[01]$/) {$self->{interruptible} = $val?0:1}
+         elsif ($var eq 'orphan' && $val =~ /^(?:terminate|reregister(?:_safe)?)$/) {$self->{orphan} = $val}
+         else {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: unrecognized key or wrong value in ($e)"; last}
+          
+      # lock command
+      } elsif ($e =~ /^lock\s+/) {
+         my ($tmp) = $e =~ /^lock\s+(.*)/;
+         if (!lockAM(parseCmd($tmp))) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: locking $tmp failed in ($e)"; last}
+          
+      # release command
+      } elsif ($e =~ /^release\s+/) {
+         my ($tmp) = $e =~ /^release\s+(.*)/;
+         if (!releaseAM(parseCmd($tmp))) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: releasing $tmp failed in ($e)"; last}
+    
+      # pause command
+      } elsif ($e =~ /^pause/) {
+         my ($tmp) = $e =~ /^pause\s*(.*)/;
+         if (defined $tmp) {
+            my $result = parseCmd($tmp);
+            unless (defined $result) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: $tmp failed in ($e)"; last}
+            else {$self->{timeout} = $result}
+         }
+         else {$self->{timeout} = $self->{macro_delay}}
+         $self->{mainline_delay} = $real_num;
+         $self->{subline_delay} = $i;
+         last
+    
+      # log command
+      } elsif ($e =~ /^log\s+/) {
+         my ($tmp) = $e =~ /^log\s+(.*)/;
+         my $result = parseCmd($tmp);
+         unless (defined $result) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: $tmp failed in ($e)"; last}
+         else {message "[macro log] $result\n", "macro"}
+         $self->{timeout} = $self->{macro_delay};
+         $self->{mainline_delay} = $real_num;
+         $self->{subline_delay} = $i;
+         last
+      }
+    
+      # do command
+      elsif ($e =~ /^do\s/) {
+         my ($tmp) = $e =~ /^do\s+(.*)/;
+         if ($tmp =~ /^macro\s+/) {
+            my ($arg) = $tmp =~ /^macro\s+(.*)/;
+            if ($arg =~ /^reset/) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: use 'release' instead of 'macro reset'"}
+            elsif ($arg eq 'pause' || $arg eq 'resume') {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: do not use 'macro pause' or 'macro resume' within a macro"}
+            elsif ($arg =~ /^set\s/) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: do not use 'macro set'. Use \$foo = bar"}
+            elsif ($arg eq 'stop') {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: use 'stop' instead"}
+            elsif ($arg !~ /^(?:list|status)$/) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: use 'call $arg' instead of 'macro $arg'"}
+         }
+         elsif ($tmp =~ /^eval\s+/) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: do not mix eval in the sub-line"}
+         elsif ($tmp =~ /^ai\s+clear$/) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: do not mess around with ai in macros"}
+         last if defined $self->{error};
+         my $result = parseCmd($tmp);
+         unless (defined $result) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: command $tmp failed"; last}
+         $self->{timeout} = $self->{macro_delay};
+         $self->{mainline_delay} = $real_num;
+         $self->{subline_delay} = $i;
+         $self->{result} = $result;
+         last
+                   
+      # "call", "[", "]", ":", "if", "while", "end" and "goto" commands block
+      } elsif ($e =~ /^(?:call|\[|\]|:|if|end|goto|while)\s*/i) {
+         $self->{error} = "Line $real_num sub-line $i\n[Reason:] Use saperate line for HERE --> $e <-- HERE";
+         last
+    
+      # sub-routine
+      } elsif (my ($sub) = $e =~ /^(\w+)\s*\(.*?\)$/) {
+         my $sub_error = 1;
+         foreach my $e (@macro_block) {if ($e eq $sub) {$sub_error = 0; parseCmd($e)}}
+         if ($sub_error)   {
+            $self->{error} = "Line $real_num sub-line $i\n[macro] $self->{name} error in sub-line $i: sub-routine $sub in --> $e <-- not found!!!";
+            last
+         } 
+    
+      ##################### End ##################
+      } else {
+         #$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: unrecognized assignment in ($e)"
+         message "Error in $self->{line}: $real_line\nWarning: Ignoring Unknown Command in sub-line $i: ($e)\n", "menu";
+      }
+      $i++
+   }
+}
+
+sub newThen {
+   my ($then, $self, $errtpl) = @_;
+
+   if ($then =~ /^goto\s/) {
+      my ($tmp) = $then =~ /^goto\s+([a-zA-Z][a-zA-Z\d]*)$/;
+      if (exists $self->{label}->{$tmp}) {
+         $self->{line} = $self->{label}->{$tmp}
+      }
+      else {$self->{error} = "$errtpl: cannot find label $tmp"}
+   }
+   elsif ($then =~ /^call\s+/) {
+      my ($tmp) = $then =~ /^call\s+(.*)/;
+      if ($tmp =~ /\s/) {
+         my ($name, $times) = $tmp =~ /(.*?)\s+(.*)/;
+         my $ptimes = parseCmd($times);
+         if (defined $ptimes) {
+            if ($ptimes > 1) {
+               $self->{subcall} = new Macro::Script($name, $ptimes)
+            }
+            elsif ($ptimes == 1) {
+               my $lastname = $self->{name};
+               my $lastline = $self->{line};
+               $self->{subcall} = new Macro::Script($name, $ptimes, $lastname, $lastline)
+            }
+            else {
+               $self->{subcall} = new Macro::Script($name)
+            }
+         }
+      }
+      else {$self->{subcall} = new Macro::Script($tmp)}
+      unless (defined $self->{subcall}) {$self->{error} = "$errtpl: failed to call script"}
+      else {
+         $self->{subcall}->regSubmacro;
+         $self->{timeout} = $self->{macro_delay}
+      }
+   }
+   elsif ($then eq "stop") {$self->{finished} = 1}
+}
+
+
+sub statement {
+   my ($temp_multi, $self, $errtpl) = @_;
+   my ($first, $cond, $last) = $temp_multi =~ /^\s*"?(.*?)"?\s+([<>=!~]+?)\s+"?(.*?)"?\s*$/;
+   if (!defined $first || !defined $cond || !defined $last) {$self->{error} = "$errtpl: syntax error in if statement"}
+   else {
+      my $pfirst = parseCmd(refined_macroKeywords($first)); my $plast = parseCmd(refined_macroKeywords($last));
+      unless (defined $pfirst && defined $plast) {$self->{error} = "$errtpl: either '$first' or '$last' has failed"}
+      elsif (cmpr($pfirst, $cond, $plast)) {return 1}
+   }
+   return 0
+}
+
+sub particle {
+   # I need to test this main code alot becoz it will be disastrous if something goes wrong
+   # in the if statement block below
+
+   my ($text, $self, $errtpl) = @_;
+   my @brkt;
+
+   if ($text =~ /\(/) {
+      @brkt = txtPosition($text, $self, $errtpl);
+      $brkt[0] = multi($brkt[0], $self, $errtpl) if !bracket($brkt[0]) && $brkt[0] =~ /[\(\)]/ eq "";
+      $text = extracted($text, @brkt);
+   }
+
+   unless ($text =~ /\(/) {return $text}
+   $text = particle($text, $self, $errtpl)
+}
+
+sub multi {
+   my ($text, $self, $errtpl) = @_;
+   my ($i, $n, $ok, $ok2) = (0, 0, 1, 0);
+   my %save;
+
+   while ($text =~ /(\|{2}|\&{2})/g) {
+      # Check if we put the wrong '&&' or '||' in the statement
+      # Logically, each clean statement(none-bracket statement),
+      # cant use the simbol '&&' or '||' together. Infact, it must be saperated
+      # by using round brackets '(' and ')' in the 1st place
+
+      $save{$i} = $1;
+      if ($i > 0) {
+         $n = $i - 1;
+         if ($save{$i} ne $save{$n}) {
+            my $s = $text;
+            $ok = 0;
+            #$s =~ s/($save{$i})/\($1\) <-- HERE/g;    # Later maybe? ;p
+            $self->{error} = "Wrong Conditions: $errtpl ($save{$n} vs $save{$i})"
+         }
+      }
+      $i++
+   }
+
+   if ($save{$n} eq "||" && $ok && $i > 0) {
+      my @split = split(/\s*\|{2}\s*/, $text);
+      foreach my $e (@split) {
+         next if $e eq "0";
+         return 1 if $e eq "1" || $e =~ /^\d+$/;
+         return 1 if statement($e, $self, $errtpl)
+      }
+      return 0
+   }
+   elsif ($save{$n} eq "&&" && $ok && $i > 0) {
+      my @split = split(/\s*\&{2}\s*/, $text);
+      foreach my $e (@split) {
+         if ($e eq "1" || ($e =~ /^\d+$/ && $e > 0)) {next}
+         elsif ($e eq "0") {return 0}
+         next if statement($e, $self, $errtpl);
+         return 0
+      }
+      return 1
+   }
+   elsif ($i == 0) {
+      return $text if $text =~ /^\d+$/;
+      return statement($text, $self, $errtpl)
+   }
+}
+
+sub txtPosition {
+   # This sub will deal which bracket is belongs to which statement,
+   # Using this, will capture the most correct statement to be checked 1st before the next statement,
+   # Ex: ((((1st statement)2nd statement)3rd statement)4th statement)
+   # will return: $new[0] = "1st statement", $new[1] = 4, $new[2] = 16

+   my ($text, $self, $errtpl) = @_;
+   my ($start, $i) = (0, 0);
+   my (@save, @new, $first, $last);
+   my @w = split(//, $text);
+
+   foreach my $e (@w) {
+      if ($e eq ")" && $start) {
+          $last = $i; last
+      }
+      elsif ($e eq "(") {
+         if ($start) {undef @save; undef $first}
+         $start = 1; $first = $i;
+      }
+      else {if ($start) {push @save, $e}}
+      $i++
+   }
+
+   $self->{error} = "$errtpl: You probably missed 1 or more closing round-\nbracket ')' in the statement." if !defined $last;
+
+   $new[0] = join('', @save);
+   $new[1] = $first;
+   $new[2] = $last;
+   return @new
+}
+
+sub extracted {
+   # Normally we just do substract s/// or s///g or using while grouping for s{}{} to delete or replace...
+   # but for some cases, the perl substract is failed... atleast for this text
+   # ex: $text = "(1 || 0) && 1 && 0" (or I might missed some info for the substract function?)
+   # so, below code will simply ignore the (1 || 0) but will replace it with $brkt[0] which is either 1 or 0,
+   # in return, the new $text will be in this format: $text = "1 && 1 && 0" if the $brkt[0] happened to be 1.
+
+   my ($text, @brkt) = @_;
+   my @save;
+   my @w = split(//, $text);
+
+   my $txt_lenght = scalar(@w);
+
+   for (my $i = 0; $i < $txt_lenght; $i++) {
+      if ($i == $brkt[1]) {push @save, $brkt[0]; next}
+      next if $i > $brkt[1] && $i <= $brkt[2];
+      push @save, $w[$i];
+      next
+   }

+   $text = join('', @save);
+   return $text
+}
+
+sub refined_macroKeywords {
+   # To make sure if there is really no more @special keywords
+
+   my @pair = $_[0] =~ /\@($macroKeywords)\s*\(\s*(.*)\s*\)/i;
+   return $_[0] unless @pair;
+
+   $pair[1] = parseCmd($pair[1]);
+   my $new = "@".$pair[0]."(".$pair[1].")";   #sorry! cheap code ;p
+   return $new
+}
+
+sub bracket {
+   # Scans $text for @special keywords
+
+   my ($text, $dbg) = @_;
+   my @brkt; my $i = 0;
+
+   while ($text =~ /(\@)?($macroKeywords)?\s*\(\s*([^\)]+)\s*/g) {
+      my ($first, $second, $third) = ($1, $2, $3);
+      unless (defined $first && defined $second && !bracket($third, 1)) {
+         message "Bracket Detected: $text <-- HERE\n", "menu" if $dbg;
+         $brkt[$i] = 1
+      }
+      else {$brkt[$i] = 0}
+      $i++
+   }
+
+   foreach my $e (@brkt) {
+      if ($e == 1) {return 1}
+   }
+
+   return 0
+}
+
1;
\ No newline at end of file



Parser.PM - Enable Perl Sub-Routine In Macro Scripting and Enable comments at the back of macro line.
Code:
--- https://openkore.svn.sourceforge.net/svnroot/openkore/plugins/macro/trunk/Macro/Parser.pm   Wed May 20 12:08:43 2009
+++ C:/.../plugins/Macro/Parser.pm   My working copy
@@ -7,6 +7,7 @@
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(parseMacroFile parseCmd);
+our @EKSPORT_OK = qw(parseCmd);

use Globals;
use List::Util qw(max min sum);
@@ -24,17 +25,20 @@
   my ($file, $no_undef) = @_;
   unless ($no_undef) {
      undef %macro;
-      undef %automacro
+      undef %automacro;
+      undef @macro_block
   }

   my %block;
   my $tempmacro = 0;
+   my $inBlock = 0;
   open FILE, "<:utf8", $file or return 0;
   foreach (<FILE>) {
-      s/^\s*#.*$//;      # remove comments
-      s/^\s*//;          # remove leading whitespaces
-      s/\s*[\r\n]?$//g;  # remove trailing whitespaces and eol
-      s/  +/ /g;         # trim down spaces
+      s/(.*)[\s\t]+#.*$/$1/;   # remove last comments
+      s/^\s*#.*$//;      # remove comments
+      s/^\s*//;      # remove leading whitespaces
+      s/\s*[\r\n]?$//g;   # remove trailing whitespaces and eol
+      s/  +/ /g;      # trim down spaces
      next unless ($_);

      if (!%block && /{$/) {
@@ -44,6 +48,8 @@
            $macro{$value} = []
         } elsif ($key eq 'automacro') {
            %block = (name => $value, type => "auto")
+         } elsif ($key eq 'sub') {
+            %block = (name => $value, type => "sub")
         } else {
            %block = (type => "bogus");
            warning "$file: ignoring line '$_' (munch, munch, strange block)\n"
@@ -91,6 +97,31 @@
         next
      }
    
+      if (%block && $block{type} eq "sub") {
+         if ($_ eq "}") {
+            if ($inBlock > 0) {
+               $macro_sub = $macro_sub.$_;
+               $inBlock--;
+               next
+            }
+            $macro_sub = "sub ".$block{name}." {".$macro_sub."}";
+            eval $macro_sub;
+            message "[macro] registering sub $block{name} ...\n", "menu";
+            push(@macro_block, $block{name});
+            undef %block, undef $macro_sub;
+            $inBlock = 0
+         } else {
+            if ($_ =~ /{$/) {$inBlock++}
+            if ($macro_sub eq "") {
+               $macro_sub = $_;
+            }
+            else {
+               $macro_sub = $macro_sub.$_;
+            }
+         }
+         next
+      }
+    
      if (%block && $block{type} eq "bogus") {
         if ($_ eq "}") {undef %block}
         next
@@ -162,6 +193,24 @@
   return @pair
}

+# parses all macro perl sub-routine found in the macro script
+sub parseSub {
+   #Taken from sub parseKw :D
+   my @full = $_[0] =~ /(?:^|\s+)(\w+)s*((s*(.*?)s*).*)$/i;
+   my @pair = ($full[0]);
+   my ($bracketed) = extract_bracketed ($full[1], '()');
+   return unless $bracketed;
+   push @pair, substr ($bracketed, 1, -1);
+
+   return unless @pair;
+
+   while ($pair[1] =~ /(?:^|\s+)(\w+)\s*\(/) {
+      @pair = parseSub ($pair[1])
+   }
+
+   return @pair
+}
+
# substitute variables
sub subvars {
# should be working now
@@ -190,11 +239,11 @@
sub parseCmd {
   return "" unless defined $_[0];
   my $cmd = $_[0];
-   my ($kw, $arg, $targ, $ret);
+   my ($kw, $arg, $targ, $ret, $sub, $val);

   # refresh global vars only once per command line
   refreshGlobal();
-

   while (($kw, $targ) = parseKw($cmd)) {
      $ret = "_%_";
      # first parse _then_ substitute. slower but more safe
@@ -235,9 +284,20 @@
         $cmd =~ s/\@$kw\s*\(\s*$targ\s*\)/$ret/
      }
   }

+   # any round bracket(pair) found after parseKw sub-routine were treated as macro perl sub-routine
+   undef $ret; undef $arg;
+   while (($sub, $val) = parseSub($cmd)) {
+      $arg = subvars($val);
+      my $sub1 = $sub."(".$arg.")";
+      $ret = eval($sub1);
+      return unless defined $ret;
+      $val = q4rx $val;    
+      $cmd =~ s/$sub\s*\(\s*$val\s*\)/$ret/g
+   }

   $cmd = subvars($cmd);
   return $cmd
}

-1;
\ No newline at end of file
+1;



Data.PM - New playerguild syntax for automacro block(credit: buggless). See also playerguild syntax in Automacro.PM diff and macro.pl diff
Example HERE, with a minor changes to the src/Settings.PM
Code:
--- https://openkore.svn.sourceforge.net/svnroot/openkore/plugins/macro/trunk/Macro/Data.pm   Wed May   Wed May 20 12:08:18 2009
+++ C:/.../plugins/Macro/Data.pm   My Working Copy
@@ -5,13 +5,16 @@

require Exporter;
our @ISA = qw(Exporter);
-our @EXPORT = qw(%macro %automacro %varStack $queue $onHold %amSingle %amMulti $macroKeywords);
+our @EXPORT = qw(@macro_block $macro_sub $inBlock %macro %automacro %varStack $queue $onHold %amSingle %amMulti $macroKeywords);

+our @macro_block;
+our $macro_sub;
our %macro;
our %automacro;
our %varStack;
our $queue;
our $onHold;
+our $inBlock;

our %amSingle = (
   'map' => 1,          # map check
@@ -34,8 +37,9 @@
   'macro_delay' => 1,  # option: default macro delay
   'hook' => 1,         # check: openkore hook
   'priority' => 1,     # option: automacro priority
-   'exclusive' => 1,     # option: is macro interruptible
-   'eval' => 1        # check : eval
+   'exclusive' => 1,    # option: is macro interruptible
+   'playerguild' => 1,  # check: player guilds
+   'eval' => 1            # check : eval
 
);

@@ -62,7 +66,8 @@
   'inventory' => 1,    # check: item amount in inventory
   'storage' => 1,      # check: item amount in storage
   'shop' => 1,         # check: item amount in shop
-   'cart' => 1          # check: item amount in cart
+   'cart' => 1,         # check: item amount in cart
+   'localtime' => 1     # check: localtime
);

our $macroKeywords =
@@ -86,7 +91,8 @@
   "eval"         . "|" .
   "arg"          . "|" .
   "listitem"     . "|" .
+      "pm"         . "|" .
   "listlenght"
;

-1;
\ No newline at end of file
+1;

Automacro.PM -

1. New playerguild syntax
2. A monster in Automacro syntax v2.0.2
3. A spell in Automacro syntax v2.0.2
4. Enable a Variable in Automacro Condition/s v2.0.2
5. A New localtime syntax in Automacro v2.0.2


Code:
--- https://openkore.svn.sourceforge.net/svnroot/openkore/plugins/macro/trunk/Macro/Automacro.pm   Wed May 20 12:07:46 2009
+++ C:/.../plugins/Macro/Automacro.pm   My Working Copy
@@ -6,7 +6,7 @@
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(releaseAM lockAM automacroCheck consoleCheckWrapper);
-our @EXPORT = qw(checkVar checkVarVar checkLoc checkLevel checkLevel checkClass
+our @EXPORT = qw(checkLocalTime checkVar checkVarVar checkLoc checkPersonGuild checkLevel checkLevel checkClass
   checkPercent checkStatus checkItem checkPerson checkCond checkCast
   checkEquip checkMsg checkMonster checkAggressives checkConsole checkMapChange
   checkNotMonster);
@@ -33,11 +33,8 @@

   refreshGlobal($var);

-   if (exists $varStack{$var}) {
-      return cmpr($varStack{$var}, $cond, $val)
-   } else {
-      return $cond eq "!="
-   }
+   if (exists $varStack{$var}) {return cmpr($varStack{$var}, $cond, $val)}
+   else {return $cond eq "!="}
}

# checks for location ######################################
@@ -75,40 +72,162 @@
   return $not?1:0
}

+# check for pc local time
+sub checkLocalTime {
+   my ($cond, $hr, $min) = $_[0] =~ /([<>=!]+)?\s*(\d{2})?:(\d{2})?$/;
+   return 0 if $cond eq "" || $hr eq "" || $min eq "";
+
+   my $time = $hr * 3600 + $min * 60;
+   my (undef, $lc_min, $lc_hr) = localtime;
+   my $lc_time = $lc_hr * 3600 + $lc_min * 60;
+
+   return cmpr($lc_time, $cond, $time)?1:0;
+}
+
+# check for ($playersList guild) vs (guild.txt or guild list)
+sub checkPersonGuild {
+   my ($guild, $trigger, $arg) = @_;
+   return 0 if !defined $guild || !defined $trigger || !defined $arg;

+   my $actor;

+   if ($trigger eq 'charNameUpdate') {$actor = $arg}
+   else {$actor = $arg->{player}}

+   return 0 unless defined $actor->{guild};
+   my $guildName = $actor->{guild}{name};
+   my $dist = $config{clientSight};
+
+   my $not = 0;
+   if ($guild =~ /^not\s+/) {$not = 1; $guild =~ s/^not +//g}
+   if ($guild =~ /(^.*),\s*(\d+)\s*$/) {$guild = $1; $dist = $2}

+   return 0 unless (distance(calcPosition($char), calcPosition($actor)) <= $dist);

+   $varStack{".lastPlayerID"} = undef;
+   $varStack{".lastGuildName"} = undef;
+   $varStack{".lastGuildNameBinID"} = undef;
+   $varStack{".lastGuildNameBinIDDist"} = undef;
+   $varStack{".lastGuildNameBinIDName"} = undef;
+   $varStack{".lastGuildNameBinIDJobName"} = undef;
+

+   if ($guild eq 'guild.txt') {
+      my @gld;
+      if (open(FILE, "<", Settings::getControlFilename("guild.txt"))) {
+         while (<FILE>) {
+            $_ =~ s/\x{FEFF}//g;
+            chomp($_);
+            next if ($_ =~ /^[\n\r#]/);
+            $_ =~ /^(.*)$/; $_ =~ s/\s+$//; $_ =~ s/^\s+//;
+            push @gld, $_;
+            #$guild = $guild .',' unless ($guild eq ''); #$guild = $guild . $_;
+         }
+         close FILE;
+           }
+           if (@gld) {$guild = join(' , ', @gld)}
+           else {$guild = ''}
+        }
+       
+   if (defined $guild && existsInList($guild, $guildName)) {
+      return 0 if $not;
+      $varStack{".lastPlayerID"} = unpack("V1", $actor->{ID});
+      $varStack{".lastGuildName"} = $guildName;
+      $varStack{".lastGuildNameBinID"} = $actor->{binID};
+      $varStack{".lastGuildNameBinIDDist"} = sprintf("%.1f", distance(calcPosition($char), calcPosition($actor)));
+      $varStack{".lastGuildNameBinIDName"} = $actor->{name};
+      $varStack{".lastGuildNameBinIDJobName"} = $jobs_lut{$actor->{jobID}};
+      return 1
+   }
+   elsif (defined $guild && $not) {
+      $varStack{".lastPlayerID"} = unpack("V1", $actor->{ID});
+      $varStack{".lastGuildName"} = $guildName;
+      $varStack{".lastGuildNameBinID"} = $actor->{binID};
+      $varStack{".lastGuildNameBinIDDist"} = sprintf("%.1f", distance(calcPosition($char), calcPosition($actor)));
+      $varStack{".lastGuildNameBinIDName"} = $actor->{name};
+      $varStack{".lastGuildNameBinIDJobName"} = $jobs_lut{$actor->{jobID}};
+      return 1;
+   }
+
+   return 0
+}
+
# checks for base/job level ################################
# uses cmpr (Macro::Utils)
sub checkLevel {
-   my ($cond, $level) = $_[0] =~ /([<>=!]+)\s*(\d+)/;
+   my ($cond, $level) = $_[0] =~ /([<>=!]+)\s*(\$[a-zA-Z][a-zA-Z\d]*|\d+|\d+\s*\.{2}\s*\d+)\s*$/;
+   if ($level =~ /^\s*\$/) {
+      my ($var) = $level =~ /^\$([a-zA-Z][a-zA-Z\d]*)\s*$/;
+      return 0 unless defined $var;
+      if (exists $varStack{$var}) {$level = $varStack{$var}}
+      else {return 0}
+   }
   return cmpr($char->{$_[1]}, $cond, $level)
}

# checks for player's jobclass #############################
sub checkClass {
   return 0 unless defined $char->{jobID};
-   return lc($_[0]) eq lc($::jobs_lut{$char->{jobID}})?1:0
+   my $class = $_[0];
+   if ($class =~ /^\s*\$/) {
+      my ($var) = $class =~ /^\$([a-zA-Z][a-zA-Z\d]*)\s*$/;
+      return 0 unless defined $var;
+      if (exists $varStack{$var}) {$class = $varStack{$var}}
+      else {return 0}
+   }
+   return lc($class) eq lc($::jobs_lut{$char->{jobID}})?1:0
}

# checks for HP/SP/Weight ##################################
# uses cmpr (Macro::Utils)
sub checkPercent {
   my ($arg, $what) = @_;
-   my ($cond, $amount) = $arg =~ /([<>=!]+)\s*(\d+%?)/;
+   my ($cond, $amount) = $arg =~ /([<>=!]+)\s*(\$[a-zA-Z][a-zA-Z\d]*%?|\d+%?|\d+\s*\.{2}\s*\d+%?)\s*$/;
   if ($what =~ /^(?:hp|sp|weight)$/) {
      return 0 unless (defined $char->{$what} && defined $char->{$what."_max"});
-      if ($amount =~ /\d+%$/ && $char->{$what."_max"}) {
+      if ($amount =~ /^\s*(?:\d+|\d+\s*\.{2}\s*\d+)%$/ && $char->{$what."_max"}) {
         $amount =~ s/%$//;
         return cmpr(($char->{$what} / $char->{$what."_max"} * 100), $cond, $amount)
-      } else {
-         return cmpr($char->{$what}, $cond, $amount)
+      }
+      elsif ($amount =~ /^\s*\$/) {
+         my ($var, $percent) = $amount =~ /^\$([a-zA-Z][a-zA-Z\d]*)(%)?\s*/;
+         return 0 unless defined $var;
+         if ((defined $percent || $percent eq "%") && defined $char->{$what."_max"}) {
+            if (exists $varStack{$var}) {
+               $amount = $varStack{$var};
+               return cmpr(($char->{$what} / $char->{$what."_max"} * 100), $cond, $amount)
+            }
+         } else {
+            if (exists $varStack{$var}) {
+               $amount = $varStack{$var};
+               return cmpr($char->{$what}, $cond, $amount)
+            }
+         }
      }
-   } elsif ($what eq 'cweight') {
+      else {return cmpr($char->{$what}, $cond, $amount)}
+   }
+   elsif ($what eq 'cweight') {
      return 0 unless (defined $cart{weight} && defined $cart{weight_max});
-      if ($amount =~ /\d+%$/ && $cart{weight_max}) {
+      if ($amount =~ /^\s*(?:\d+|\d+\s*\.{2}\s*\d+)%$/ && $cart{weight_max}) {
         $amount =~ s/%$//;
         return cmpr(($cart{weight} / $cart{weight_max} * 100), $cond, $amount)
-      } else {
-         return cmpr($cart{weight}, $cond, $amount)
      }
+      elsif ($amount =~ /^\s*\$/) {
+         my ($var, $percent) = $amount =~ /^\$([a-zA-Z][a-zA-Z\d]*)(%)?\s*/;
+         return 0 unless defined $var;
+         if ((defined $percent || $percent eq "%") && defined $cart{weight_max}) {
+            if (exists $varStack{$var}) {
+               $amount = $varStack{$var};
+               return cmpr(($cart{weight} / $cart{weight_max} * 100), $cond, $amount)
+            }
+         } else {
+            if (exists $varStack{$var}) {
+               $amount = $varStack{$var};
+               return cmpr($cart{weight}, $cond, $amount)
+            }
+         }
+      }
+      else {return cmpr($cart{weight}, $cond, $amount)}
   }
   return 0
}
@@ -130,7 +249,6 @@
   return $not?1:0
}

-
# checks for item conditions ##############################
# uses: getInventoryAmount, getCartAmount, getShopAmount,
#       getStorageAmount (Macro::Utils?)
@@ -142,17 +260,24 @@
      return 0
   }
   my ($item, $cond, $amount) = getArgs($check);
+   if ($item =~ /^\$/) {
+      my ($var) = $item =~ /^\$([a-zA-Z][a-zA-Z\d]*)\s*/;
+      return 0 unless defined $var;
+      if (exists $varStack{$var}) {$item = $varStack{$var}}
+      else {return 0}
+   }
+   if ($amount =~ /^\$/) {
+      my ($var1) = $amount =~ /^\$([a-zA-Z][a-zA-Z\d]*)\s*/;
+      return 0 unless defined $var1;
+      if (exists $varStack{$var1}) {$amount = $varStack{$var1}}
+      else {return 0}
+   }
   my $what;
   if ($where eq 'inv')  {$what = getInventoryAmount($item)}
   if ($where eq 'cart') {$what = getCartAmount($item)}
-   if ($where eq 'shop') {
-      return 0 unless $shopstarted;
-      $what = getShopAmount($item)
-   }
-   if ($where eq 'stor') {
-      return 0 unless $::storage{opened};
-      $what = getStorageAmount($item)
-   }
+   if ($where eq 'shop') {return 0 unless $shopstarted; $what = getShopAmount($item)}
+   if ($where eq 'stor') {return 0 unless $::storage{opened}; $what = getStorageAmount($item)}
+
   return cmpr($what, $cond, $amount)?1:0
}

@@ -173,7 +298,13 @@
# checks arg1 for condition in arg3 #######################
# uses: cmpr (Macro::Utils)
sub checkCond {
-   my ($cond, $amount) = $_[1] =~ /([<>=!]+)\s*(\d+)/;
+   my ($cond, $amount) = $_[1] =~ /([<>=!]+)\s*(\$[a-zA-Z][a-zA-Z\d]*|\d+|\d+\s*\.{2}\s*\d+)\s*$/;
+   if ($amount =~ /^\s*\$/) {
+      my ($var) = $amount =~ /^\$([a-zA-Z][a-zA-Z\d]*)\s*$/;
+      return 0 unless defined $var;
+      if (exists $varStack{$var}) {$amount = $varStack{$var}}
+      else {return 0}
+   }
   return cmpr($_[0], $cond, $amount)?1:0
}

@@ -208,16 +339,86 @@

# checks for a spell casted on us #########################
# uses: distance, judgeSkillArea (Utils?)
+#sub checkCast {
+#   my ($cast, $args) = @_;
+#   $cast = lc($cast);
+#   my $pos = calcPosition($char);
+#   return 0 if $args->{sourceID} eq $accountID;
+#   my $target = (defined $args->{targetID})?$args->{targetID}:0;
+#   if (($target eq $accountID ||
+#      ($pos->{x} == $args->{x} && $pos->{y} == $args->{y}) ||
+#      distance($pos, $args) <= judgeSkillArea($args->{skillID})) &&
+#      existsInList($cast, lc(Skill->new(idn => $args->{skillID})->getName()))) {return 1}
+#   return 0
+#}
sub checkCast {
   my ($cast, $args) = @_;
   $cast = lc($cast);
   my $pos = calcPosition($char);
   return 0 if $args->{sourceID} eq $accountID;
   my $target = (defined $args->{targetID})?$args->{targetID}:0;
-   if (($target eq $accountID ||
-      ($pos->{x} == $args->{x} && $pos->{y} == $args->{y}) ||
-      distance($pos, $args) <= judgeSkillArea($args->{skillID})) &&
-      existsInList($cast, lc(Skill->new(idn => $args->{skillID})->getName()))) {return 1}
+   my $source = $args->{sourceID};
+   return 0 if $target eq $source;
+
+   if (($target eq $accountID || ($pos->{x} == $args->{x} && $pos->{y} == $args->{y}) || distance($pos, $args) <= judgeSkillArea($args->{skillID})) && existsInList($cast, lc(Skill->new(idn => $args->{skillID})->getName()))) {
+    
+      if (my $actor = $monstersList->getByID($source)) {
+         $varStack{".caster"} = "monster";
+         $varStack{".casterName"} = $actor->{name};
+         $varStack{".casterID"} = $actor->{binID};
+         $varStack{".casterLoc"} = "$actor->{pos_to}{x}" . " $actor->{pos_to}{y}";
+         $varStack{".casterDist"} = sprintf("%.1f", distance($pos, calcPosition($actor)))
+
+      } elsif (my $actor = $playersList->getByID($source)) {
+         $varStack{".caster"} = "player";
+         $varStack{".casterName"} = (defined $actor->{name})?$actor->{name}:"Unknown";
+         $varStack{".casterID"} = $actor->{binID};
+         $varStack{".casterLoc"} = "$actor->{pos_to}{x}" . " $actor->{pos_to}{y}";
+         $varStack{".casterDist"} = sprintf("%.1f", distance($pos, calcPosition($actor)));
+
+      } else {return 0}
+
+      $varStack{".casterSkill"} = Skill->new(idn => $args->{skillID})->getName();
+      if (($args->{x} == 0) && ($args->{y} == 0)) {$varStack{".casterTarget"} = "You"}
+      else {$varStack{".casterTarget"} = "$args->{x}" . " $args->{y}"}
+      return 1
+
+   } elsif (existsInList($cast, lc(Skill->new(idn => $args->{skillID})->getName()))) {
+      return 0 if !$char->{'party'} || !%{$char->{'party'}};
+      if (my $actor = $monstersList->getByID($source)) {
+         foreach my Actor::Player $player (@{$playersList->getItems()}) {
+            return 0 unless $player->{'party'}{'name'} eq $char->{'party'}{'name'};
+            if ($target eq $player->{ID} || ($player->{pos_to}{x} == $args->{x} && $player->{pos_to}{y} == $args->{y}) || distance($player->{pos}, $args) <= judgeSkillArea($args->{skillID})) {
+               $varStack{".caster"} = "monster";
+               $varStack{".casterName"} = $actor->{name};
+               $varStack{".casterID"} = $actor->{binID};
+               $varStack{".casterLoc"} = "$actor->{pos_to}{x}" . " $actor->{pos_to}{y}";
+               $varStack{".casterSkill"} = Skill->new(idn => $args->{skillID})->getName();
+               $varStack{".casterTarget"} = "$args->{x}" . " $args->{y}";
+               $varStack{".casterDist"} = sprintf("%.1f", distance($pos, calcPosition($actor)));
+               return 1
+            }
+         }
+
+      } elsif (my $actor = $playersList->getByID($source)) {
+         my $actor_party = (exists $actor->{'party'})?$actor->{'party'}{'name'}:"";
+         return 0 if $actor_party eq $char->{'party'}{'name'};
+         foreach my Actor::Player $player (@{$playersList->getItems()}) {
+            my $player_party = (exists $player->{'party'})?$player->{'party'}{'name'}:"";
+            return 0 unless $player_party eq $char->{'party'}{'name'};
+            if ($target eq $player->{ID} || ($player->{pos_to}{x} == $args->{x} && $player->{pos_to}{y} == $args->{y}) || distance($player->{pos}, $args) <= judgeSkillArea($args->{skillID})) {
+               $varStack{".caster"} = "player";
+               $varStack{".casterName"} = (defined $actor->{name})?$actor->{name}:"Unknown";
+               $varStack{".casterID"} = $actor->{binID};
+               $varStack{".casterLoc"} = "$actor->{pos_to}{x}" . " $actor->{pos_to}{y}";
+               $varStack{".casterSkill"} = Skill->new(idn => $args->{skillID})->getName();
+               $varStack{".casterTarget"} = "$args->{x}" . " $args->{y}";
+               $varStack{".casterDist"} = sprintf("%.1f", distance($pos, calcPosition($actor)));
+               return 1
+            }
+         }
+      } else {return 0}
+   }
   return 0
}

@@ -260,40 +461,110 @@
   return 0
}

-# checks for monster, credits to illusionist
+# checks for monster ...
sub checkMonster {
-   my $monsterList = $_[0];
+   my $line = $_[0];
+   my ($not, $mercenary, $use, $monsterList, $cond);
+   my $mondist = $config{clientSight} || 20;
+
+   if ($line =~ /^\s*(.*),?\s+([<>=!~]+)\s+(\d+|\d+\s+.{2}\s+\d+)\s*$/) {
+      ($monsterList, $cond, $mondist) = ($1, $2, $3)
+   } else {
+      $monsterList = $line;
+      $cond = "<="
+   }
+
+   if ($monsterList =~ /^(not|mercenary)\s+(.*)\s*$/) {
+      if ($1 eq "not") {$not = 1; $monsterList = $2}
+      else {$mercenary = 1; $use = 1; $monsterList = $2}
+   }
+
   foreach (@monstersID) {
      next unless defined $_;
-      if (existsInList($monsterList, $monsters{$_}->{name})) {
+      if ($mercenary) {
+         #Whose the mercenary's master,
+         #update later ;p
+         my $mypos = calcPosition($char);
         my $pos = calcPosition($monsters{$_});
-         my $val = sprintf("%d %d %s", $pos->{x}, $pos->{y}, $field->name);
+         my $dist = sprintf("%.1f",distance($pos, $mypos));
+         if (existsInList($monsterList, $monsters{$_}->{name}) && $dist < 3) {$use = 0; last}      }
+      elsif ($not) {
+         next if existsInList($monsterList, $monsters{$_}->{name});
+         my $mypos = calcPosition($char);
+         my $pos = calcPosition($monsters{$_});
+         my $dist = sprintf("%.1f",distance($pos, $mypos));
+         my $val = sprintf("%d %d %s", $pos->{x}, $pos->{y}, $field->{name});
         $varStack{".lastMonster"} = $monsters{$_}->{name};
         $varStack{".lastMonsterPos"} = $val;
-         return 1
+         $varStack{".lastMonsterDist"} = $dist;
+         $varStack{".lastMonsterID"} = $monsters{$_}->{binID};
+         return cmpr($dist, $cond, $mondist)
+      } else {
+         if (existsInList($monsterList, $monsters{$_}->{name})) {
+            my $counter;
+            my $mypos = calcPosition($char);
+            my $pos = calcPosition($monsters{$_});
+            my $dist = sprintf("%.1f", distance($mypos, $pos));
+            my $val = sprintf("%d %d %s", $pos->{x}, $pos->{y}, $field->{name});
+            $varStack{".lastMonster"} = $monsters{$_}->{name};
+            $varStack{".lastMonsterPos"} = $val;
+            $varStack{".lastMonsterDist"} = $dist;
+            $varStack{".lastMonsterID"} = $monsters{$_}->{binID};
+            for (my $i = 0; $i < @::monstersID; $i++) {
+               next if $::monstersID[$i] eq "";
+               my $monster = Actor::get($::monstersID[$i]);
+               if ($monster->name eq $monsters{$_}->{name}) {
+                  if ($monster->{binID} eq $monsters{$_}->{binID}) {
+                     $counter++;
+                     next
+                  } else {
+                     my $monsToMonDist = sprintf("%.1f",distance($pos, $monster->{pos_to}));
+                     $counter++ if $monsToMonDist < 12;
+                     next
+                  }
+               }
+               next
+            }
+            $varStack{".lastMonsterCount"} = $counter;
+            return cmpr($dist, $cond, $mondist)
+         }
      }
   }
+   return 1 if ($use);
   return 0
}

# checks for forbidden monster
# quick hack, maybe combine it with checkMonster later
sub checkNotMonster {
+   my $mondist = $config{clientSight};
   my $monsterList = $_[0];
+   if ($monsterList =~ /,\s+\d+\s*$/) {
+      $mondist = $monsterList =~ /,\s+(\d+)\s*$/;
+      $monsterList = s/, +\d+\s*$//g;
+   }
   foreach (@monstersID) {
      next unless defined $_;
      next if existsInList($monsterList, $monsters{$_}->{name});
-      return 1
+      my $mypos = calcPosition($char);
+      my $pos = calcPosition($monsters{$_});
+      my $dist = sprintf("%.1f",distance($pos, $mypos));
+      return $dist <= $mondist ?1:0
   }
   return 0
}

# checks for aggressives
sub checkAggressives {
-   my ($cond, $amount) = $_[0] =~ /([<>=!]+)\s*(\d+)/;
+   my ($cond, $amount) = $_[0] =~ /([<>=!]+)\s*(\$[a-zA-Z][a-zA-Z\d]*|\d+|\d+\s*\.{2}\s*\d+)\s*$/;
+   if ($amount =~ /^\s*\$/) {
+      my ($var) = $amount =~ /^\$([a-zA-Z][a-zA-Z\d]*)\s*$/;
+      return 0 unless defined $var;
+      if (exists $varStack{$var}) {$amount = $varStack{$var}}
+      else {return 0}
+   }
   return cmpr(scalar ai_getAggressives, $cond, $amount)
}
-
# checks for console message
sub checkConsole {
   my ($msg, $arg) = @_;
@@ -322,6 +593,11 @@

# checks for eval
sub checkEval {
+   if ($_[0] =~ /;/) {
+      my @eval = split(/\s*;\s*/, $_[0]);
+      foreach my $e (@eval) {return 1 if checkEval($e)}
+      return 0
+   }
   return eval $_[0];
}

@@ -431,6 +707,10 @@
         if ($trigger eq 'packet_mapChange') {
         next CHKAM unless checkMapChange($automacro{$am}->{mapchange})
         } else {next CHKAM}
+      } elsif (defined $automacro{$am}->{playerguild}) {
+          if (($trigger eq 'player') || ($trigger eq 'charNameUpdate')) {
+         next CHKAM unless checkPersonGuild($automacro{$am}->{playerguild},$trigger,$args)
+         } else {next CHKAM}
      }

      next CHKAM if (defined $automacro{$am}->{map}    && $automacro{$am}->{map} ne $field->name);
@@ -441,6 +721,7 @@
      foreach my $i (@{$automacro{$am}->{monster}})    {next CHKAM unless checkMonster($i)}
      foreach my $i (@{$automacro{$am}->{aggressives}}){next CHKAM unless checkAggressives($i)}
      foreach my $i (@{$automacro{$am}->{location}})   {next CHKAM unless checkLoc($i)}
+      foreach my $i (@{$automacro{$am}->{localtime}})  {next CHKAM unless checkLocalTime($i, "")}
      foreach my $i (@{$automacro{$am}->{var}})        {next CHKAM unless checkVar($i, "")}
      foreach my $i (@{$automacro{$am}->{varvar}})     {next CHKAM unless checkVar($i, "varvar")}
      foreach my $i (@{$automacro{$am}->{base}})       {next CHKAM unless checkLevel($i, "lv")}
@@ -495,4 +776,4 @@
   }
}

-1;
\ No newline at end of file
+1;



macro.pl - Adding hooks for the playerguild syntax
Code:
--- https://openkore.svn.sourceforge.net/svnroot/openkore/plugins/macro/trunk/macro.pl   Wed May 20 12:39:22 2009
+++ C:/.../plugins/macro.pl   Wed May 20 12:36:27 2009
@@ -113,6 +113,8 @@
      if (defined $automacro{$a}->{mapchange} && !defined $load{'packet_mapChange'}) {$load{'packet_mapChange'} = 1}
      if (defined $automacro{$a}->{hook} && !defined $load{$automacro{$a}->{hook}}) {$load{$automacro{$a}->{hook}} = 1}
      if (defined $automacro{$a}->{console} && !defined $hookToLog) {$hookToLog = 1}
+      if (defined $automacro{$a}->{playerguild} && !defined $load{'player'}) {$load{'player'} = 1}
+      if (defined $automacro{$a}->{playerguild} && !defined $load{'charNameUpdate'}) {$load{'charNameUpdate'} = 1}
   }
   foreach my $l (keys %load) {
      message "[macro] hooking to $l\n";
@@ -218,11 +220,11 @@
      message "Macro::Parser ".$Macro::Parser::rev."\n";
      message "Macro::Utilities ".$Macro::Utilities::rev."\n"
   ### debug
-#   } elsif ($arg eq 'varstack') {
-#      message "varstack\n", "list";
-#      foreach my $v (keys %varStack) {
-#         message "\$varStack{$v} = [".$varStack{$v}."]\n"
-#      }
+   } elsif ($arg eq 'varstack') {
+      message "Varstack List\n", "menu";
+      foreach my $v (keys %varStack) {
+         message "\$varStack{$v} = [".$varStack{$v}."]\n", "menu"
+      }
   ### parameter: probably a macro
   } else {
      if (defined $queue) {
@@ -271,4 +273,4 @@

Arachno <arachnophobia at users dot sf dot net>

-=cut
\ No newline at end of file
+=cut


This macro will be triggered when the slave is lost, it will send pm to master and the master will send a command to move to its current location and also the slave sends command to move the master to its current location.
Pros: faster party search, followBot 1 will just set a "meeting point" for both master and slave, but this one,, they will move to each others place, thus meeting them FAST
Cons: when the master is dead and at town, he will still go to the slave even his HP is low, so i use the SIT MACRO below, to ensure that if the master has low hp he wont move until the slave heals him =)

NOTE: in config.txt followBot should be 0


Macro for SLAVE


Code:
################################
######FIND MASTER###############
################################
#find master
automacro findMaster {
   timeout 3
   console /^I lost my master/
   call {
   $master = @config (followTarget)
   do pm "$master" x $.map $.pos
   }
}
automacro findMaster2 {
   timeout 3
   console /^Calculating route to find master/
   call {
   $master = @config (followTarget)
   do pm "$master" x $.map $.pos
   }
}
#goto master
automacro gotoMaster {
   pm /x (.*) (.*) (.*)/
   call {
   $pm = $.lastpm
   if ($pm != $master) stop
   do move $.lastMatch1 $.lastMatch2 $.lastMatch3
   }
}
#when master is found
automacro foundMaster {
   console /^Found my master!/
   call {
   do pm "$master" clear
   }
}

Advance Party Search Macro


Macro for MASTER


Code:
#######################################
########FIND SLAVE#####################
#######################################
#slave is lost
automacro findSlave {
   pm /x (.*) (.*) (.*)/
   call {
   $slavemap = $.lastMatch1
   $slavemapx = $.lastMatch2
   $slavemapy = $.lastMatch3
   $mymap = $.map
   if ($slavemap == $mymap) goto findslave
   do pm "$.lastpm" x $.map $.pos
   stop
:findslave
   do pm "$.lastpm" x $.map $.pos
   do move $slavemap $slavemapx $slavemapy
   }
}
#when slave is found
automacro clear {
   pm /clear/
   call {
   do eval AI::clear("move", "route");
   }
}


i don know if this is advance or what but when i used this my bots meet up each other fast and doesn't lost each other at a great distance.

better change

for MASTER

Code:
route_step 15

to
Code:
route_step 8
or 3 or 2 but just dont put 0, 3 is enaf, and 8 is the best

for SLAVE

Code:
route_step 15

to
Code:
route_step 18


and also
set a pausemap for your master(to make sure slave will be first to enter the map for a sec.)
find these:

Code:
pauseCharServer 0
pauseMapServer

and change to this
Code:
pauseCharServer 1
pauseMapServer 1

in your config.txt

BattleGround Krieger von Midgard / KVM Battle Ground

#TABOG'S KVMbot MACRO (CROIX)#
#this version still got some issues regarding coordinates#
#i'm still a noob in macro so pls help =)#
# GO GO GO pROVALK#
#SAVE YOUR CHARACTER in GEFFEN#


automacro maroll {
location geffen
exclusive 1
run-once 1
call {
do move 112 65
do talknpc 109 66 c c r0 n
release maroll
}
}


automacro bat_room 154 150 {
location bat_room 154 150
run-once 1
call {
do c tabog para sa 2010!!!
do move 167 125
pause 1
do talknpc 164 121 c r0 c
pause 2
release bat_room 154 150
}
}


automacro bat_room 154 151 {
location bat_room 154 151
run-once 1
call {
do move 167 125
pause 1
do talknpc 164 121 c r0 c
pause 2
release bat_room 154 151
}
}


automacro bat_room 155 150 {
location bat_room 155 150
run-once 1
call {
do move 167 125
pause 1
do talknpc 164 121 c r0 c
pause 2
release bat_room 155 150
}
}


automacro spamnpc {
location bat_room 167 125
exclusive 1
run-once 0
call spamtalk
}



macro spamtalk {
do talknpc 164 121 c r0 c
pause 2
stop
}


automacro SpamPub {
location bat_room 169 207
exclusive 1
run-once 0
call EnterPub
}


macro EnterPub {
do chat join 0
pause 1
stop
}


automacro fight {
location bat_c01 138 63
run-once 1
call {
do move 68 122
release fight
}
}


automacro fight2 {
location bat_c01 68 122
run-once 1
call {
do move 138 63
release fight2
}
}


automacro KVMpoint {
location bat_c01 147 55
exclusive 1
run-once 0
call collectpoint1
}


macro collectpoint1 {
do talk 9
call collectpoint2
}


macro collectpoint2 {
do talk 10
pause 1
stop
}

automacro reload {
console /Map Change/i
run-once 1
call {
do reload macro
release reload
}
}

automacro pk1 {
console /Player (.*) \((\d+)\) attacks you.*/i
call {
do kill $.lastMatch2
}
}

automacro pk2 {
console /Player (.*) \((\d+)\) uses (.*) on you - Dmg.*/i
call {
do kill $.lastMatch2
}
}

automacro pk3 {
console /Player (.*) \((\d+)\) is casting (.*) on you.*/i
var .lastMatch1 != PutSlaveNameHereRemoveThisLineIfBottingSolo
call {
do kill $.lastMatch2
}
}


Battle Ground Macros

I post this macro here so other player form valkyrie (Philippines Server) will not buy their macro from other player...

Macros.txt
Code:
# v1.0: Tierra Maps Only
       # Features: AI choice
       #       PK Behavior
       #       Random Map

       # Notes:
       # The error in SpawnPub automacro is normal.
       # This is to spam the chat room incase the room is full.

       # Save and setup your Bot in Aldebaran Town

        automacro Maroll {
           location aldebaran
           exclusive 1
           run-once 1
           call {
              do move 151 110
              do talknpc 146 109 c c r0 n
         release Maroll
           }
        }

        automacro GoHome {
           location not aldebaran
           location not bat_room
           location not bat_a01
           location not bat_a02
           exclusive 1
           run-once 1
           call {
          do move aldebaran
          release GoHome
           }
        }

        automacro BGroomEntry {
           location bat_room
           exclusive 1
      priority 1
           run-once 0
           call {
     
          $randomMap = @eval($::config{Battle_Random})

          if ($randomMap == 0) goto ContBGRoom
          if ($randomMap == 1) goto RandomMapTierra

          :RandomMapTierra
         
          $RandomMapChoice = @random ("tierra1","tierra2","tierra3","tierra4")

          do conf Battle_Map $RandomMapChoice
          goto ContBGRoom
         
           :ContBGRoom
           call CharPos
          }
        }

       automacro TalkNPC1 {
          location bat_room 132 175 135 169
          exclusive 1
          run-once 0
          call TalkBGnpc
          }

       automacro TalkNPC2 {
          location bat_room 148 175 151 170
          exclusive 1
          run-once 0
          call TalkBGnpc
          }

       automacro TalkNPC3 {
          location bat_room 132 131 135 125
          exclusive 1
          run-once 0
          call TalkBGnpc
          }

       automacro TalkNPC4 {
          location bat_room 148 132 151 125
          exclusive 1
          run-once 0
          call TalkBGnpc
          }

          automacro SpawnPubT1 {
             location bat_room 57 223
             exclusive 1
             run-once 0
             call EnterPub
          }

          automacro SpawnPubT2 {
             location bat_room 114 223
             exclusive 1
             run-once 0
             call EnterPub
          }

          automacro SpawnPubT3 {
             location bat_room 57 207
             exclusive 1
             run-once 0
             call EnterPub
          }

          automacro SpawnPubT4 {
             location bat_room 114 207
             exclusive 1
             run-once 0
             call EnterPub
          }

          automacro SpawnPubF1 {
             location bat_room 85 223
             exclusive 1
             run-once 0
             call EnterPub
          }

          automacro SpawnPubF2 {
             location bat_room 141 224
             exclusive 1
             run-once 0
             call EnterPub
          }

          automacro SpawnPubF3 {
             location bat_room 85 207
             exclusive 1
             run-once 0
             call EnterPub
          }

          automacro SpawnPubF4 {
             location bat_room 141 207
             exclusive 1
             run-once 0
             call EnterPub
          }

       automacro tierraEntry1 {
           location bat_a01
           exclusive 1
           run-once 0
      priority 1
           call TierraAI
           }

       automacro tierraEntry2 {
           location bat_a02
           exclusive 1
           run-once 0
      priority 1
           call TierraAI
           }

       automacro PKAtk {
          console /Player (.*) \((\d+)\) attacks You.*/i
     exclusive 1
          run-once 1
          call RespondPK
          }
     
       automacro PKSkill {
          console /Player (.*) \((\d+)\) uses (.*) on you.*/i
          exclusive 1
          run-once 1
          call RespondPK
          }

       automacro TierraExit1 {
          location bat_a01 50 374
          exclusive 1
          run-once 0
          call GetBadge
       }
     
       automacro TierraExit2 {
          location bat_a01 43 17
          exclusive 1
          run-once 0
          call GetBadge
       }

       automacro TierraExit3 {
          location bat_a02 50 374
          exclusive 1
          run-once 0
          call GetBadge
       }

       automacro TierraExit4 {
          location bat_a02 43 17
          exclusive 1
          run-once 0
          call GetBadge
       }

    macro CharPos {

       $Map = @eval($::config{Battle_Map})

       if ($Map == tierra1) goto Pos1
       if ($Map == tierra2) goto Pos2
       if ($Map == tierra3) goto Pos3
       if ($Map == tierra4) goto Pos4
       if ($Map == flavius1) goto Pos1
       if ($Map == flavius2) goto Pos2
       if ($Map == flavius3) goto Pos3
       if ($Map == flavius4) goto Pos4

          :Pos1
          $randomX1 = @random ("132","133")
          $randomY1 = @random ("171","172","173","174")
          do move $randomX1 $randomY1
          goto endCharPos

          :Pos2
          $randomX2 = @random ("148","149")
          $randomY2 = @random ("171","172","173","174")
          do move $randomX2 $randomY2
          goto endCharPos

          :Pos3
          $randomX3 = @random ("132","133")
          $randomY3 = @random ("125","126","127","128")
          do move $randomX3 $randomY3
          goto endCharPos

          :Pos4
          $randomX4 = @random ("148","149")
          $randomY4 = @random ("125","126","127","128")
          do move $randomX4 $randomY4
          goto endCharPos

          :endCharPos
          stop
       }

    macro TalkBGnpc {

       $Map = @eval($::config{Battle_Map})

       if ($Map == tierra1) goto NPC1
       if ($Map == tierra2) goto NPC2
       if ($Map == tierra3) goto NPC3
       if ($Map == tierra4) goto NPC4
       if ($Map == flavius1) goto NPC5
       if ($Map == flavius2) goto NPC6
       if ($Map == flavius3) goto NPC7
       if ($Map == flavius4) goto NPC8

          :NPC1
          do talknpc 124 178 c r0 n
          stop

          :NPC2
          do talknpc 140 178 c r0 n
          stop

          :NPC3
          do talknpc 125 121 c r0 n
          stop

          :NPC4
          do talknpc 140 121 c r0 n
          stop

          :NPC5
          do talknpc 133 178 c r0 n
          stop

          :NPC6
          do talknpc 148 178 c r0 n
          stop

          :NPC7
          do talknpc 133 121 c r0 n
          stop

          :NPC8
          do talknpc 148 121 c r0 n
          stop
       }

    macro TierraAI   {

       $AI = @eval($::config{Battle_AI})
     
       if ($AI == 0) goto AI1
       if ($AI == 1) goto AI2

       :AI1
       call IdleAI
       stop

       :AI2
       $Map = @eval($::config{Battle_Map})
     
          if ($Map == tierra1) goto AI11
          if ($Map == tierra2) goto AI11
          if ($Map == tierra3) goto AI22
          if ($Map == tierra4) goto AI22

          :AI11
          do move 162 49
          do a 0
          goto EndAI2

          :AI22
          do move 171 345
          do a 0
          goto EndAI2

          :EndAI2
          stop
          }

       macro IdleAI {

          $Map = @eval($::config{Battle_Map})
     
          if ($Map == tierra1) goto Pub1
          if ($Map == tierra2) goto Pub1
          if ($Map == tierra3) goto Pub2
          if ($Map == tierra4) goto Pub2

   :Pub1
   $PubX1 = @random ("351","352","353","354","355")
   $PubY1 = @random ("350","351")
        do move $PubX1 $PubY1
   goto EndPub

   :Pub2
   $PubX2 = @random ("352","353","354","355","356")
   $PubY2 = @random ("47","48")
        do move $PubX2 $PubY2
   goto EndPub

   :EndPub
        $randomPub = @random ("Be Right Back","Away From Keyboard","Eating","Taking a Bath","Sleeping")
        do chat create "$randomPub"
        stop
        }

       macro RespondPK {
     
       $PKPlayer = $.lastmatch2
       $PK = @eval($::config{Battle_PK})

          if ($PK == 0) goto PK1
          if ($PK == 1) goto PK2

          :PK1
          do e wah
          goto EndRespondPK

          :PK2
          do e gg
          do kill $PKPlayer
          goto EndRespondPK

             :EndRespondPK
             call TierraAI
             stop
             release PKAtk
             release PKSkill
             }

       macro EnterPub {
          do chat join 0
          pause 1
          stop
          }

       macro GetBadge {
          do talk 2
               stop
          }


Config.txt
Code:
##### Battle Grounds Config #####

Battle_Map tierra1
Battle_AI 1
Battle_PK 0
Battle_Random 0

#################################

This will help you:
Code:
NPC locations:
tierra1 | flavius1 | tierra2 | flavius2

tierra3 | flavius3 | tierra4 | flavius4

Battle_AI
0 = Going AFK. Doing a random Pub with an excuse as a title ,
1 = Going to Attack. Tierra: Going to the enemy food and attack it.

Battle_PK
0 = If someone attacks you or use a skill on you. will not respond and will continue what you're doin (Battle_AI),
1 = If someone attacks you or use a skill on you. will respond by attacking the player with the weapon equipped.

Battle_Random
0 = will use the map specified in Battle_Map over and over again,
1 = will go to a random Map every round.

Note:spam error is normal
Code:
           #-----------------------------------------------------------------
           #----------- Battle Grounds Macro (v1.1) by noobotter ------------
           #-----------------------------------------------------------------
         
           # v1.1: Tierra Maps
           #
           # Features: AI choice
           #           Custom AFK *NEW*
           #           Random Map
           #           Battle PK *REMOVED*

           # Notes:
           # The error in SpawnPub automacro is normal.
           # This is to spam the chat room incase the room is full.

           # Save and setup your Bot in Aldebaran Town

    macro CustomIdleAI {

       # Modify the following to personalize your custom AFK AI.

       $useCustomIdleAI = No
       $customX = x
       $customY = y
       $customPub = @random ("Custom1","Custom2","Custom3","Custom4","Custom5")
   ##################################################################################

       if ($useCustomIdleAI == Yes) goto CustomTrigger
       if ($useCustomIdleAI == No) goto DefaultTrigger

       :CustomTrigger
       do move $customX $customY
       do chat create "$customPub"
       stop

       :DefaultTrigger
       call DefaultIdleAI
       stop
       }

            automacro Maroll {
               location aldebaran
               exclusive 1
               run-once 1
               call {
                  do move 151 110
                  do talknpc 146 109 c c r0 n
             release Maroll
               }
            }

            automacro GoHome {
               location not aldebaran
               location not bat_room
               location not bat_a01
               location not bat_a02
          location not bat_b01
          location not bat_b02
               exclusive 1
               run-once 1
               call {
              do move aldebaran
              release GoHome
               }
            }

            automacro BGroomEntry {
               location bat_room
               exclusive 1
          priority 1
               run-once 0
               call {
         
              $randomMap = @eval($::config{Battle_Random})

              if ($randomMap == 0) goto ContBGRoom
              if ($randomMap == 1) goto RandomMapTierra
              if ($randomMap == F) goto RandomMapFlavius

              :RandomMapTierra
              $RandomMapChoice = @random ("tierra1","tierra2","tierra3","tierra4")

              do conf Battle_Map $RandomMapChoice
              goto ContBGRoom
           
         :RandomMapFlavius
              $RandomMapChoice = @random ("flavius1","flavius2","flavius3","flavius4")

              do conf Battle_Map $RandomMapChoice
              goto ContBGRoom

               :ContBGRoom
               call CharPos
              }
            }

           automacro TalkNPC1 {
              location bat_room 124 175 135 168
              exclusive 1
              run-once 0
              call TalkBGnpc
              }

           automacro TalkNPC2 {
              location bat_room 140 175 151 167
              exclusive 1
              run-once 0
              call TalkBGnpc
              }

           automacro TalkNPC3 {
              location bat_room 124 131 135 124
              exclusive 1
              run-once 0
              call TalkBGnpc
              }

           automacro TalkNPC4 {
              location bat_room 148 132 151 125
              exclusive 1
              run-once 0
              call TalkBGnpc
              }

              automacro SpawnPubT1 {
                 location bat_room 57 223
                 exclusive 1
                 run-once 0
                 call EnterPub
              }

              automacro SpawnPubT2 {
                 location bat_room 114 223
                 exclusive 1
                 run-once 0
                 call EnterPub
              }

              automacro SpawnPubT3 {
                 location bat_room 57 207
                 exclusive 1
                 run-once 0
                 call EnterPub
              }

              automacro SpawnPubT4 {
                 location bat_room 114 207
                 exclusive 1
                 run-once 0
                 call EnterPub
              }

              automacro SpawnPubF1 {
                 location bat_room 85 223
                 exclusive 1
                 run-once 0
                 call EnterPub
              }

              automacro SpawnPubF2 {
                 location bat_room 141 224
                 exclusive 1
                 run-once 0
                 call EnterPub
              }

              automacro SpawnPubF3 {
                 location bat_room 85 207
                 exclusive 1
                 run-once 0
                 call EnterPub
              }

              automacro SpawnPubF4 {
                 location bat_room 141 207
                 exclusive 1
                 run-once 0
                 call EnterPub
              }

           automacro tierraEntry1 {
               location bat_a01
               exclusive 1
               run-once 0
          priority 1
               call TierraAI
               }

           automacro tierraEntry2 {
               location bat_a02
               exclusive 1
               run-once 0
          priority 1
               call TierraAI
               }

           automacro tierraAtkStone1 {
               location bat_a01 170 349 175 343
               exclusive 1
               run-once 0
               call {
          do a 0
          stop
          }
               }

           automacro tierraAtkStone2 {
               location bat_a01 161 55 166 44
               exclusive 1
               run-once 0
               call {
          do a 0
          stop
          }
               }

           automacro tierraAtkStone3 {
               location bat_a02 170 349 175 343
               exclusive 1
               run-once 0
               call {
          do a 0
          stop
          }
               }

           automacro tierraAtkStone4 {
               location bat_a02 161 55 166 44
               exclusive 1
               run-once 0
               call {
          do a 0
          stop
          }
               }

           automacro TierraExit1 {
              location bat_a01 50 374
              exclusive 1
              run-once 0
              call GetBadge
           }
         
           automacro TierraExit2 {
              location bat_a01 43 17
              exclusive 1
              run-once 0
              call GetBadge
           }

           automacro TierraExit3 {
              location bat_a02 50 374
              exclusive 1
              run-once 0
              call GetBadge
           }

           automacro TierraExit4 {
              location bat_a02 43 17
              exclusive 1
              run-once 0
              call GetBadge
           }

        macro CharPos {

           $Map = @eval($::config{Battle_Map})

           if ($Map == tierra1) goto Pos1
           if ($Map == tierra2) goto Pos2
           if ($Map == tierra3) goto Pos3
           if ($Map == tierra4) goto Pos4
           if ($Map == flavius1) goto Pos1
           if ($Map == flavius2) goto Pos2
           if ($Map == flavius3) goto Pos3
           if ($Map == flavius4) goto Pos4

              :Pos1
              $randomX1 = @random ("124","125","132","133")
              $randomY1 = @random ("171","172","173","174")
              do move $randomX1 $randomY1
              goto endCharPos

              :Pos2
              $randomX2 = @random ("140","141","148","149")
              $randomY2 = @random ("171","172","173","174")
              do move $randomX2 $randomY2
              goto endCharPos

              :Pos3
              $randomX3 = @random ("124","125","132","133")
              $randomY3 = @random ("125","126","127","128")
              do move $randomX3 $randomY3
              goto endCharPos

              :Pos4
              $randomX4 = @random ("140","141","148","149")
              $randomY4 = @random ("125","126","127","128")
              do move $randomX4 $randomY4
              goto endCharPos

              :endCharPos
              stop
           }

        macro TalkBGnpc {

           $Map = @eval($::config{Battle_Map})

           if ($Map == tierra1) goto NPC1
           if ($Map == tierra2) goto NPC2
           if ($Map == tierra3) goto NPC3
           if ($Map == tierra4) goto NPC4
           if ($Map == flavius1) goto NPC5
           if ($Map == flavius2) goto NPC6
           if ($Map == flavius3) goto NPC7
           if ($Map == flavius4) goto NPC8

              :NPC1
              do talknpc 124 178 c r0 n
              stop

              :NPC2
              do talknpc 140 178 c r0 n
              stop

              :NPC3
              do talknpc 125 121 c r0 n
              stop

              :NPC4
              do talknpc 140 121 c r0 n
              stop

              :NPC5
              do talknpc 133 178 c r0 n
              stop

              :NPC6
              do talknpc 148 178 c r0 n
              stop

              :NPC7
              do talknpc 133 121 c r0 n
              stop

              :NPC8
              do talknpc 148 121 c r0 n
              stop
           }

        macro TierraAI   {

           $AI = @eval($::config{Battle_AI})
         
           if ($AI == 0) goto AI1
           if ($AI == 1) goto AI2

           :AI1
           call CustomIdleAI
           stop

           :AI2
           $Map = @eval($::config{Battle_Map})
         
              if ($Map == tierra1) goto AI11
              if ($Map == tierra2) goto AI11
              if ($Map == tierra3) goto AI22
              if ($Map == tierra4) goto AI22

              :AI11
              do move 162 49
              goto EndAI2

              :AI22
              do move 171 345
              goto EndAI2

              :EndAI2
              stop
              }

           macro DefaultIdleAI {

              $Map = @eval($::config{Battle_Map})
         
              if ($Map == tierra1) goto Pub1
              if ($Map == tierra2) goto Pub1
              if ($Map == tierra3) goto Pub2
              if ($Map == tierra4) goto Pub2

       :Pub1
       $PubX1 = @random ("351","352","353","354","355")
       $PubY1 = @random ("350","351")
            do move $PubX1 $PubY1
       goto EndPub

       :Pub2
       $PubX2 = @random ("352","353","354","355","356")
       $PubY2 = @random ("47","48")
            do move $PubX2 $PubY2
       goto EndPub

       :EndPub
            $randomPub = @random ("Be Right Back","Away From Keyboard","Eating","Taking a

    Bath","Sleeping")
            do chat create "$randomPub"
            stop
            }
    #noobotter@yahoo.com
           macro EnterPub {
              do chat join 0
              pause 1
              stop
              }

           macro GetBadge {
              do talk 2
                   stop
              }

Source http://darkmoon.ath.cx/viewtopic.php?f=25&t=1884

This is V1.1

Original code support Flavius map.

To Prontera Server Malaysia Ragnarok

u need Change at bottom of code

Code:
           macro GetBadge {
              do talk 2
              pause 10
                   stop
              }

This fix code will not make your bot disconnect after attack Food Deploy

I can see many of them rather not atk Food Deploy and to wait room timeout which is 20 minute, and make other wait too long :evil:

DO Command on PM

This macro was based on Do command from pm by windows98SE@thaikore on the old forums.

This macro will let a bot do a certain Do Command on a PM when the sender is on the list of allowed players.
This is useful in using bots while playing non-bots simultaneously.

Code:
##  DO Command at PM  ##

automacro DOonPM {
   console /\(From: (.*)\) : do (.*)/
   run-once 1
   call {
   #Multiple IF Statements can be added for flexibility
   # Player1 is an in-game name
   # Player2 is an in-game name
   if ("$.lastMatch1" == "Player1") goto ok
   if ("$.lastMatch1" == "Player2") goto ok
   do pm "$.lastMatch1" Asa... #any message to say rejection on request...
   release DOonPM
   stop
:ok
   release DOonPM
   do $.lastMatch2
   pause 2
   do pm "$.lastMatch1" done
   stop
   }
}

Example Situation 1 (Player1 is allowed):

Player1 PMs Bot: do openshop
Bot opens the shop
Bot PMs Player1: done

Example Situation 2 (Player2 is also allowed):

Player2 PMs Bot: do e heh
Bot uses emoticon heh
Bot PMs Player2: done

Example Situation 3 (Player3 is not allowed):

Player3 PMs Bot: do relog 9999999
Bot does nothing
Bot PMs Player3: Asa...

Example Situation 4 (Player1 is allowed):

Player1 PMs Bot: do relog 9999999
Bot relogs

I'm using this to manually trade and chat

automacro doCommand {
   console /\(From: (.*)\) : do (.*)/
   call {
      $nick = $.lastMatch1
      $auth = @eval (defined $::overallAuth{"$nick"} ? $::overallAuth{"$nick"}:"None")
      if ($auth == 1) goto auth
      do pm $.lastMatch1 Pardon...?
      stop
   :auth 
      do $.lastMatch2
      pause
      do pm $.lastMatch1 All done.
   }
}

Basically I made it check your nick on the overallAuth.txt.
With that you don't need to change the macro, just add people to the file by console commands or char password.
Open overallAuth.txt
put your char name inside with flag 1.
example :
Code:
charName 1

try pm char using 'exp'.

Note : this already been implement on openkore, read openkore manual. Btw ths is share's macro topic.
automacro simpleCommando {
   pm /do (.*)/i
   call {
$nick = $.lastpm
   $auth = @eval (defined $::overallAuth{"$nick"} ? $::overallAuth{"$nick"}:"None")
   if ($auth == 1) goto auth
   do pm "$.lastpm" You are not authorize to use this command.
   stop
:auth
   do $.lastMatch1
   do pm "$.lastpm" Command Accepted! :3
   }
}
try its just the same. You should be authorized by the bot to do this,

Protect The Priest Macro

-Using Status Recovery
-or/or both-
-Commanding the master

Update : May 09, 2010

This will cast status recovery on the aggressive monster that attacks your priest, thus changing the target of the monster.
Warning : turn this off if you will use tank mode, and you will use priest as your tanker!

macro for SLAVE

Code:
automacro statusRecover {
   timeout 3
   console /Monster (.*) \((\d+)\) attacks you /i
   call {
   $m = $.lastMatch2
   do sm 72 $m
   }
}

READ:
Thx to Mushroom for correcting my codes =)

UPDATE : OR this macro =0

it will send an attack command to the MASTER to attack a monster that attacks the SLAVE
this will not work 100% of all time as bots will see different monster IDs,but in some case they are the same, so its cool =)

Updated May 09, 2010

macro for MASTER
you should use this if u are using advance party search macro, coz ur priest shall not be authorized by the master,
Code:
################################
######COMMAND###################
################################

automacro Command {
   console /\(From: (.*)\) : xd (.*)/
   call {
#####NOTE : edit $town to the map you are using storage and auto buys!####
        $town = Geffen #edit this!
        $mymap = $.map
   $xd = $.lastMatch1
   $xd2 = $.lastMatch2
        if ($mymap == $town) stop
   do $xd2
   }
}



macro for SLAVE

Code:
################################
######PROTECT ME################
################################

automacro protectMe {
   timeout 3
   console /Monster (.*) \((\d+)\) attacks you/
   call {
   $mymap = $.map
   $lockmap = @config (lockMap)
   $master = @config (followTarget)
   $follow = @config (follow)
   $mon = $.lastMatch2
   if ($follow = 0) stop
   if ($mymap != $lockmap) stop
   do pm "$master" xd a $mon
   } 
}

ok the only prob here is, when ur slave is lost, and ur master is far away, im recommending you, to use my Advance Party Search Macro  =)

1-99 Example Macro | OK 2.0.6.1 | Macro 2.0.2

Extreme V1.0 :lol:

Purpose:
Create a Novice and then simply watch it become Level 99 [Insert a job here] without moving a finger!! [In my Example it's High Wizard]
I must say that it is extremely useful for making bot armies. Before I had to level each of my bots manually which was a pain in a$$ since my bots were banned frequently.


Use:

Do not just copy paste it!!! This Macro is written for a High Rate server with a Job Changer, NPC Warp and @go command.
Use this as a reference and make your own macro that fits your needs!


Minimum Modification:
1) NPC Locations and Talk Sequences
2) Job you want
3) Maps where you want to level
4) Skills and stats you want to up
5) Weapon configuration (Melee/Range/Spells)
6) Levels at which you want the Macro to Trigger
7) Jobs at which you want Macro to Trigger
8) Your save location
9) Desired levels


Explanation of the Macro:

#############Step One (1)################

automacro Novice_1 { #First automacro which triggers when you are Level 1
exclusive 1 #This automacro cannot be interrupted by other macros
run-once 1 #This macro wont repeat again
base == 1 #This line is a Base Level Trigger
class Novice #This line is a Job Trigger [Better put it here if you want to get Advanced Jobs]

call {
do conf skillsAddAuto_list Basic Skill 9 #This line changes the config.txt to make bot level up "Basic Skill"
do c @go 0 #Warps te bot where it needs to be [If you're server doesn't have that command use Kafra\Warp Npc\Whatever]
do move 36 208 #This line moves the bot towards the Kafra to save
do talknpc 29 207 c r0 c #This is talking with Kafra and saving
do conf lockMap prt_fild05 #This line sets the map where you want to level\do stuff [Prepare portals beforehand]
do conf runFromTarget 0 #This line changes the runFromTarget to 0 in config.txt
do conf attackUseWeapon 1 #This line changes the attackUseWeapon to 1 in config.txt
do conf attackCanSnipe 0 #This line changes the attackCanSnipe to 0 in config.txt
do conf attackCheckLOS 0 #This line changes the attackCheckLOS to 0 in config.txt
}
}

#############Step Two (2)################

automacro Level_15_Becoming_Mage {
priority 1 #This is macro's priority compared to other macros [Bigger the number - lesser the priority]
exclusive 1 #This automacro cannot be interrupted by other macros
run-once 1 #This macro wont repeat again
base >= 15 #This line is a Base Level Trigger
class Novice #This line is a Job Trigger [Better put it here if you want to get Advanced Jobs]

call {
do conf lockMap prontera #This line sets the map where you want to level\do stuff [Prepare portals beforehand]
do c @go 0 #Warps the bot where it needs to be [If your server doesn't have that command use Kafra\Warp Npc\Whatever]
do move 170 200 #Moves the bot near needed location
do talknpc 172 198 c c c r0 r1 c r0 c #Talks to the Job Changer
}
}

#############Step Three (3)################

automacro Mage_15 {
priority 2 #This is macro's priority compared to other macros [Bigger the number - lesser the priority]
exclusive 1 #This automacro cannot be interrupted by other macros
run-once 1 #This macro wont repeat again
class Mage #This line is a Job Trigger [Better put it here if you want to get Advanced Jobs]

call {
do c @go 0 #Warps te bot where it needs to be [If your server doesn't have that command use Kafra\Warp Npc\Whatever]
do move 167 192 #Moves the bot near needed location
do talknpc 176 205 c r1 r7 c r0 #Manually talks to Warp NPC to get where it needs
do conf lockMap prt_fild05 #This line sets the map where you want to level\do stuff [Prepare portals beforehand]
}
}

#############Step Four (4)################

automacro Level_20 {
priority 3 #This is macro's priority compared to other macros [Bigger the number - lesser the priority]
exclusive 1 #This automacro cannot be interrupted by other macros
run-once 1 #This macro wont repeat again
base >= 20 #This line is a Base Level Trigger
class Mage #This line is a Job Trigger [Better put it here if you want to get Advanced Jobs]

call {
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do c @go 0 #Warps the bot where it needs to be [If your server doesn't have that command use Kafra\Warp Npc\Whatever]
do conf lockMap prt_maze02 #This line sets the map where you want to level\do stuff [Prepare portals beforehand]
do conf attackUseWeapon 0 #This line changes the attackUseWeapon to 0 in config.txt
do conf attackCanSnipe 1 #This line changes the attackCanSnipe to 1 in config.txt
do conf attackCheckLOS 1 #This line changes the attackCheckLOS to 1 in config.txt
}
}

#############Step Five (5)################

automacro Level_50 {
priority 4 #This is macro's priority compared to other macros [Bigger the number - lesser the priority]
exclusive 1 #This automacro cannot be interrupted by other macros
run-once 1 #This macro wont repeat again
base >= 50 #This line is a Base Level Trigger
class Mage #This line is a Job Trigger [Better put it here if you want to get Advanced Jobs]

call {
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do c @go 19 #Warps the bot where it needs to be [If your server doesn't have that command use Kafra\Warp Npc\Whatever]
do conf lockMap ein_fild04 #This line sets the map where you want to level\do stuff [Prepare portals beforehand]
do conf runFromTarget 1 #This line changes the runFromTarget to 0 in config.txt
}
}

#############Step Six (6)################

automacro Level_82 {
priority 5 #This is macro's priority compared to other macros [Bigger the number - lesser the priority]
exclusive 1 #This automacro cannot be interrupted by other macros
run-once 1 #This macro wont repeat again
base >= 82 #This line is a Base Level Trigger
class Mage #This line is a Job Trigger [Better put it here if you want to get Advanced Jobs]

call {
do c @go 0 #Warps the bot where it needs to be [If your server doesn't have that command use Kafra\Warp Npc\Whatever]
do conf lockMap prontera #This line sets the map where you want to level\do stuff [Prepare portals beforehand]
do move 172 197 #Moves the bot near needed location
do talknpc 172 198 c c c r0 r0 c r0 c #Talks to the Job Changer
}
}

#############Step Seven (7)################

automacro Wizard_82 {
priority 6 #This is macro's priority compared to other macros [Bigger the number - lesser the priority]
exclusive 1 #This automacro cannot be interrupted by other macros
run-once 1 #This macro wont repeat again
class Wizard #This line is a Job Trigger [Better put it here if you want to get Advanced Jobs]

call {
do c @go 19 #Warps the bot where it needs to be [If yore server doesn't have that command use Kafra\Warp Npc\Whatever]
do conf lockMap ein_fild04 #This line sets the map where you want to level\do stuff [Prepare portals beforehand]
}
}

#############Step Eight (8)################

automacro Level_99 {
priority 7 #This is macro's priority compared to other macros [Bigger the number - lesser the priority]
exclusive 1 #This automacro cannot be interrupted by other macros
run-once 1 #This macro wont repeat again
base >= 99 #This line is a Base Level Trigger
class Wizard #This line is a Job Trigger [Better put it here if you want to get Advanced Jobs]

call {
do c @go 0 #Warps the bot where it needs to be [If yore server doesn't have that command use Kafra\Warp Npc\Whatever]
do conf lockMap prontera #This line sets the map where you want to level\do stuff [Prepare portals beforehand]
do move 172 197 #Moves the bot near needed location
do talknpc 172 198 c c c r0 c r0 c #Talks to the Job Changer
}
}

#############Step Nine (9)################

automacro High_Novice_1 {
priority 8 #This is macro's priority compared to other macros [Bigger the number - lesser the priority]
exclusive 1 #This automacro cannot be interrupted by other macros
run-once 1 #This macro wont repeat again
class High Novice #This line is a Job Trigger [Better put it here if you want to get Advanced Jobs]
base == 1 #This line is a Base Level Trigger

call {
do c @go 0 #Warps the bot where it needs to be [If your server doesn't have that command use Kafra\Warp Npc\Whatever]
do move 167 192 #Moves the bot near needed location
do talknpc 176 205 c r1 r7 c r0 #Manually talks to Warp NPC to get where it needs
do conf lockMap prt_fild05 #This line sets the map where you want to level\do stuff [Prepare portals beforehand]
do conf attackUseWeapon 1 #This line changes the attackUseWeapon to 1 in config.txt
do conf attackCanSnipe 0 #This line changes the attackCanSnipe to 0 in config.txt
do conf runFromTarget 0 #This line changes the runFromTarget to 0 in config.txt
do conf attackCheckLOS 0 #This line changes the attackCheckLOS to 0 in config.txt
}
}

#############Step Ten (10)################

automacro Level_15_High {
priority 9 #This is macro's priority compared to other macros [Bigger the number - lesser the priority]
exclusive 1 #This automacro cannot be interrupted by other macros
run-once 1 #This macro wont repeat again
base >= 15 #This line is a Base Level Trigger
class High Novice #This line is a Job Trigger [Better put it here if you want to get Advanced Jobs]

call {
do skills add 1 #Level ups Basic Skill [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 1 #Level ups Basic Skill [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 1 #Level ups Basic Skill [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 1 #Level ups Basic Skill [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 1 #Level ups Basic Skill [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 1 #Level ups Basic Skill [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 1 #Level ups Basic Skill [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 1 #Level ups Basic Skill [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 1 #Level ups Basic Skill [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do conf lockMap prontera #This line sets the map where you want to level\do stuff [Prepare portals beforehand]
do c @go 0 #Warps the bot where it needs to be [If yore server doesn't have that command use Kafra\Warp Npc\Whatever]
do move 172 196 #Moves the bot near needed location
do talknpc 172 198 c c c r0 c #Talks to the Job Changer
}
}

#############Step Eleven (11)################

automacro High_Mage_15 {
priority 10 #This is macro's priority compared to other macros [Bigger the number - lesser the priority]
exclusive 1 #This automacro cannot be interrupter by other macros
run-once 1 #This macro wont repeat again
class High Magician #This line is a Job Trigger [Better put it here if you want to get Advanced Jobs]

call {
do c @go 0 #Warps the bot where it needs to be [If yore server doesn't have that command use Kafra\Warp Npc\Whatever]
do move 167 192 #Moves the bot near needed location
do talknpc 176 205 c r1 r7 c r0 #Manually talks to Warp NPC to get where it needs
do conf lockMap prt_fild05 #This line sets the map where you want to level\do stuff [Prepare portals beforehand]
}
}

#############Step Twelve (12)################

automacro Level_20_High {
priority 11 #This is macro's priority compared to other macros [Bigger the number - lesser the priority]
exclusive 1 #This automacro cannot be interrupted by other macros
run-once 1 #This macro wont repeat again
class High Magician #This line is a Job Trigger [Better put it here if you want to get Advanced Jobs]
base >= 20 #This line is a Base Level Trigger

call {
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do c @go 0 #Warps the bot where it needs to be [If yore server doesn't have that command use Kafra\Warp Npc\Whatever]
do conf lockMap prt_maze02 #This line sets the map where you want to level\do stuff [Prepare portals beforehand]
do conf attackUseWeapon 0 #This line changes the attackUseWeapon to 0 in config.txt
do conf attackCanSnipe 1 #This line changes the attackCanSnipe to 1 in config.txt
do conf attackCheckLOS 1 #This line changes the attackCheckLOS to 1 in config.txt
}
}

#############Step Thirteen (13)################

automacro Level_50_High {
priority 12 #This is macro's priority compared to other macros [Bigger the number - lesser the priority]
exclusive 1 #This automacro cannot be interrupted by other macros
run-once 1 #This macro wont repeat again
class High Magician #This line is a Job Trigger [Better put it here if you want to get Advanced Jobs]
base >= 50 #This line is a Base Level Trigger

call {
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do skills add 19 #Level ups Fire Bolt [Sometimes skillsAddAuto_List glitches, so I prefer doing it manually]
do c @go 19 #Warps the bot where it needs to be [If yore server doesn't have that command use Kafra\Warp Npc\Whatever]
do conf lockMap ein_fild04 #This line sets the map where you want to level\do stuff [Prepare portals beforehand]
do conf runFromTarget 1 #This line changes the runFromTarget to 1 in config.txt
}
}

#############Step Fourteen (14)################

automacro Level_82_High {
priority 13 #This is macro's priority compared to other macros [Bigger the number - lesser the priority]
exclusive 1 #This automacro cannot be interupted by other macros
run-once 1 #This macro wont repeat again
class High Magician #This line is a Job Trigger [Better put it here if you want to get Advanced Jobs]
base >= 82 #This line is a Base Level Trigger

call {
do c @go 0 #Warps the bot where it needs to be [If yore server doesn't have that command use Kafra\Warp Npc\Whatever]
do conf lockMap prontera #This line sets the map where you want to level\do stuff [Prepare portals beforehand]
do move 172 197 #Moves the bot near needed location
do talknpc 172 198 c c c r0 c r0 c #Talks to the Job Changer
}
}

#############Step Fiveteen (15)################

automacro High_Wizard_82 {
priority 14 #This is macro's priority compared to other macros [Bigger the number - lesser the priority]
exclusive 1 #This automacro cannot be interupted by other macros
run-once 1 #This macro wont repeat again
base >= 82 #This line is a Base Level Trigger
class High Wizard #This line is a Job Trigger [Better put it here if you want to get Advanced Jobs]

call {
do c @go 19 #Warps the bot where it needs to be [If yore server doesn't have that command use Kafra\Warp Npc\Whatever]
do conf lockMap ein_fild04 #This line sets the map where you want to level\do stuff [Prepare portals beforehand]
}
}




#############Step Sixteen (16)################

automacro Level_99_High {
priority 15 #This is macro's priority compared to other macros [Bigger the number - lesser the priority]
exclusive 1 #This automacro cannot be interupted by other macros
run-once 1 #This macro wont repeat again
base >= 99 #This line is a Base Level Trigger
class High Wizard #This line is a Job Trigger [Better put it here if you want to get Advanced Jobs]

call {
do c @go 0 #Warps the bot where it needs to be [If yore server doesn't have that command use Kafra\Warp Npc\Whatever]
do quit #Exits the bot when level 99 is reached [Adjust to your own needs]
}
}



####### Precatious For Geographer Map ########

automacro unstuck {
timeout 500 #Executes macro every 500 seconds
base >= 50 #Triggered when Base Level is more that 50
location not prontera #Triggered when the bot is not in Prontera

call {
do c @go 19 #Waprs the bot to Einbroch near the lockMap
}
}

######## Stat_Add Unstuck ######

automacro stat_add {
timeout 60 #Executes every 60 seconds
base > 1 #Triggered when Base Level is more that 1

call {
do stat_add int #Adds one stat point to Int [I made this little Automacro because sometimes bot's auto stat add is stuck]
}
}


Apparently now it will work even with explanation! So now you CAN copy paste it
basically it will log your death,
the monster who killed you,
the map
the date and time

Note : make a deathlog.txt inside your control folder

Code:
#######################################
##############LOG ON DEATH#############
#######################################

automacro LogOnDeath {
   console /^You have died/i
   call {
   do eval open(FILE, ">>", Settings::getControlFilename("deathlog.txt")); print FILE "Killed by $.lastMonster at $.map | $.datetime \n"; close FILE;
   }
}

Autopsy plugin.

Code:
##########################################################################
# This software is open source, licensed under the GNU General Public
# License, version 2.
# Basically, this means that you're allowed to modify and distribute
# this software. However, if you distribute modified versions, you MUST
# also distribute the source code.
# See http://www.gnu.org/licenses/gpl.html for the full license.
##########################################################################

#Autopsy.pl
#Plugin by: PlayingSafe, Openkore
#Revision 2
#Under Openkore 2.0.0 (SVN)
#How to use
#At your config file put
#logDeath 1 <-- put 1 to enable logging
#logDeathSize # <--- put your desired number of lines to save
#deathMessage <-- put the "You have died" word on your local language if kore is set to local language
#example:
#logDeathSize 25 (this will save 25 lines of console messages)
#deathMessage You have died (Default language English)

package Autopsy;

use Utils;
use strict;
use Plugins;
use Globals;
use Settings;
use Log qw(message debug);

Plugins::register('Autopsy', 'Record console messages after bot died', \&unload);
my $cHook = Log::addHook(\&cHook, "DeathLog");

sub unload {
        Log::delHook('cHook', $cHook);
}

my @messages = ();

sub cHook {
        my $type = shift;
        my $domain = shift;
        my $level = shift;
        my $currentVerbosity = shift;
        my $message = shift;
        my $user_data = shift;
        my $logfile = shift;
        my $deathmsg = shift;
        my $location = shift;

if ($level <= $currentVerbosity && $config{'logDeath'} == 1) {

        my (undef, $microseconds) = Time::HiRes::gettimeofday;
        $microseconds = substr($microseconds, 0, 2);
        my $message2 = "[".getFormattedDate(int(time)).".$microseconds] ".$message;

        push(@messages, $message2);
        my $size = scalar @messages;
        if ($size == $config{'logDeathSize'} + 1) {
                        shift(@messages);
        }
        if ($config{logAppendUsername}) {
                $logfile = "$Settings::logs_folder/deathlog_$config{username}_$config{char}.txt";
        } else {
                $logfile = "$Settings::logs_folder/deathlog.txt";
        }
        $deathmsg = $config{'deathMessage'};
        if ($message =~ /$deathmsg/) {
                my $pos = calcPosition($char);
                $location = "\nYou died at $maps_lut{$field{name}.'.rsw'} ($field{name}) : $pos->{x}, $pos->{y}\n";
                                use encoding 'utf8';
                                open(DFILE, ">>:utf8", "$logfile"); {
                                print DFILE "\n*** Start of console death log ***\n\n";
                                print DFILE @messages;
                                print DFILE $location;
                                print DFILE "\n*** End of console death log ***\n\n";
                                close(DFILE);
                        }
                }
        }
}
return 1;


Usage
Quote:
How to use
#At your config file put
#logDeath 1 <-- put 1 to enable logging
#logDeathSize # <--- put your desired number of lines to save
#deathMessage <-- put the "You have died" word on your local language if kore is set to local language
#example:
#logDeathSize 25 (this will save 25 lines of console messages)
#deathMessage You have died (Default language English)

logDeath 1
logDeathSize 50
deathMessage You have died

at the logs folder your could see how your bot die...
##########################################################################
# This software is open source, licensed under the GNU General Public
# License, version 2.
# Basically, this means that you're allowed to modify and distribute
# this software. However, if you distribute modified versions, you MUST
# also distribute the source code.
# See http://www.gnu.org/licenses/gpl.html for the full license.
##########################################################################

#Autopsy.pl
#Plugin by: PlayingSafe, Openkore
#Revision 3 by Rbin
#Openkore 2.0.0 (SVN) upper
#How to use
#At your config file put
#logDeath 1 <-- put 1 to enable logging
#logDeathSize # <--- put your desired number of lines to save
#deathMessage <-- put the "You have died" word on your local language if kore is set to local language
#example:
#logDeathSize 25 (this will save 25 lines of console messages)
#deathMessage You have died (Default language English)

package Autopsy;

use Utils;
use strict;
use Plugins;
use Globals;
use Settings;
use Log qw(message debug);

Plugins::register('Autopsy', 'Record console messages after bot died', \&unload);
my $cHook = Log::addHook(\&cHook, "DeathLog");

sub unload {
        Log::delHook('cHook', $cHook);
}

my @messages = ();

sub cHook {
        my $type = shift;
        my $domain = (shift or "console");
        my $level = (shift or 0);
        my $currentVerbosity = shift;
        my $message = shift;
        my $user_data = shift;
        my $logfile = shift;
        my $deathmsg = shift;
        my $location = shift;

if ($level <= $currentVerbosity && $config{'logDeath'} == 1) {

        my (undef, $microseconds) = Time::HiRes::gettimeofday;
        $microseconds = substr($microseconds, 0, 2);
        my $message2 = "[".getFormattedDate(int(time)).".$microseconds] ".$message;

        push(@messages, $message2);
        my $size = scalar @messages;
        if ($size == $config{'logDeathSize'} + 1) {
                        shift(@messages);
        }
        if ($config{logAppendUsername}) {
                $logfile = "$Settings::logs_folder/deathlog_$config{username}_$config{char}.txt";
        } else {
                $logfile = "$Settings::logs_folder/deathlog.txt";
        }
        $deathmsg = $config{'deathMessage'};
        if ($message =~ /$deathmsg/) {
                my $pos = calcPosition($char);
                $location = "\nYou died at $maps_lut{$field{name}.'.rsw'} ($field{name}) : $pos->{x}, $pos->{y}\n";
                                use encoding 'utf8';
                                open(DFILE, ">>:utf8", "$logfile"); {
                                print DFILE "\n*** Start of console death log ***\n\n";
                                print DFILE @messages;
                                print DFILE $location;
                                print DFILE "\n*** End of console death log ***\n\n";
                                close(DFILE);
                        }
                }
        }
}
return 1;

this should work on version 2.0.0 above

ไม่มีความคิดเห็น:

แสดงความคิดเห็น

AddThis

Share |