Page 1 of 2

An Overall Macro Plugins Diff

Posted: 20 May 2009, 01:09
by ezza
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.
openkore - Revision 6696: /plugins/macro/trunk
Utilities.PM - Enable the range numbers in (?:auto|)macro

Code: Select all

--- 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: Select all

--- 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: Select all

--- 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: Select all

--- 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.

Re: An Overall Macro Plugins Diff

Posted: 20 May 2009, 22:22
by ezza
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: Select all

--- 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: Select all

--- 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.

Re: An Overall Macro Plugins Diff

Posted: 04 Jun 2009, 01:58
by ezza
UpDated... Major Update!


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

Re: An Overall Macro Plugins Diff

Posted: 04 Jun 2009, 05:04
by h4rry84
should be already committed in r6703

Re: An Overall Macro Plugins Diff

Posted: 04 Jun 2009, 05:22
by ezza
Tq richard for the help.

Re: An Overall Macro Plugins Diff

Posted: 04 Jun 2009, 08:09
by Darki
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.

Re: An Overall Macro Plugins Diff

Posted: 04 Jun 2009, 08:26
by ezza
The diff is before its been commited... now its already in SVN r6707

Re: An Overall Macro Plugins Diff

Posted: 04 Jun 2009, 09:42
by Darki
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.

Re: An Overall Macro Plugins Diff

Posted: 04 Jun 2009, 11:44
by ezza
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...

Re: An Overall Macro Plugins Diff

Posted: 04 Jun 2009, 13:26
by Darki
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. -.-