Openkore.com
http://forums.openkore.com/

An Overall Macro Plugins Diff
http://forums.openkore.com/viewtopic.php?f=58&t=6079
Page 1 of 2

Author:  ezza [ 20 May 2009, 01:09 ]
Post subject:  An Overall Macro Plugins Diff

I would like to propose Diffs to Macro Plugins... below are 6 Diff's for 6 files (5 PM files and 1 PL file).. hope that other devs could test it.

Quote:
openkore - Revision 6696: /plugins/macro/trunk


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;





p.s: Continue to the next post due to the exceeded 60, 000+ characters. Sorry.

Author:  ezza [ 20 May 2009, 22:22 ]
Post subject:  Re: An Overall Macro Plugins Diff

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




p.s: Diff ends here... thank you for your time.

Author:  ezza [ 04 Jun 2009, 01:58 ]
Post subject:  Re: An Overall Macro Plugins Diff

UpDated... Major Update!


Included in the SVN version. Any bugs or errors report is highly appreciated. Thx.

Author:  h4rry84 [ 04 Jun 2009, 05:04 ]
Post subject:  Re: An Overall Macro Plugins Diff

should be already committed in r6703

Author:  ezza [ 04 Jun 2009, 05:22 ]
Post subject:  Re: An Overall Macro Plugins Diff

Tq richard for the help.

Author:  Darki [ 04 Jun 2009, 08:09 ]
Post subject:  Re: An Overall Macro Plugins Diff

Then, all of this is already in the SVN macro plugin version? Because I'm a little lost with the diff stuff and if I can download it already I could start working on my macros to "update" them.

Author:  ezza [ 04 Jun 2009, 08:26 ]
Post subject:  Re: An Overall Macro Plugins Diff

The diff is before its been commited... now its already in SVN r6707

Author:  Darki [ 04 Jun 2009, 09:42 ]
Post subject:  Re: An Overall Macro Plugins Diff

So, that's what I ask. xD If I download the macro from the SVN, I'll get it with the mods?

Apart from that, it'd be nice to give the macro manual a HUGE update for this, I don't mind doing a little one for the macro subforums if you want.

Author:  ezza [ 04 Jun 2009, 11:44 ]
Post subject:  Re: An Overall Macro Plugins Diff

Darki wrote:
So, that's what I ask. xD If I download the macro from the SVN, I'll get it with the mods?

Apart from that, it'd be nice to give the macro manual a HUGE update for this, I don't mind doing a little one for the macro subforums if you want.




Errr... Darki, yes!!! I'm desperate to have our macro manual back in action. If you say so.. why not :)



p.s: We could pin your temp manual 1st... and edit it untill everything is okay. Then, let our Ducumentation Writer do thier job...

Author:  Darki [ 04 Jun 2009, 13:26 ]
Post subject:  Re: An Overall Macro Plugins Diff

I'll get the instructions from your posts and put them together in the macro subforum with a little corrections and putting it a little tidier, then you can complete it with examples if you want. As soon as I update my own program I'll work on it, but I'm getting trouble because the broken links... I'm still looking for that damn BotOrganizer for example. -.-

Page 1 of 2 All times are UTC - 5 hours [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/