An Overall Macro Plugins Diff

Forum closed. All further discussion to be discussed at https://github.com/OpenKore/

Moderator: Moderators

Message
Author
ezza
Developers
Developers
Posts: 109
Joined: 04 Apr 2008, 09:50

An Overall Macro Plugins Diff

#1 Post 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.

ezza
Developers
Developers
Posts: 109
Joined: 04 Apr 2008, 09:50

Re: An Overall Macro Plugins Diff

#2 Post 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.

ezza
Developers
Developers
Posts: 109
Joined: 04 Apr 2008, 09:50

Re: An Overall Macro Plugins Diff

#3 Post by ezza »

UpDated... Major Update!


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

h4rry84
Moderators
Moderators
Posts: 234
Joined: 04 Apr 2008, 09:30
Noob?: Yes
Location: My House
Contact:

Re: An Overall Macro Plugins Diff

#4 Post by h4rry84 »

should be already committed in r6703

ezza
Developers
Developers
Posts: 109
Joined: 04 Apr 2008, 09:50

Re: An Overall Macro Plugins Diff

#5 Post by ezza »

Tq richard for the help.

Darki
Been there done that!
Been there done that!
Posts: 143
Joined: 25 Oct 2008, 08:14
Noob?: No
Location: Spain, Madrid
Contact:

Re: An Overall Macro Plugins Diff

#6 Post 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.
ImageImageImage
ImageImageImage
ImageImageImage

ezza
Developers
Developers
Posts: 109
Joined: 04 Apr 2008, 09:50

Re: An Overall Macro Plugins Diff

#7 Post by ezza »

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

Darki
Been there done that!
Been there done that!
Posts: 143
Joined: 25 Oct 2008, 08:14
Noob?: No
Location: Spain, Madrid
Contact:

Re: An Overall Macro Plugins Diff

#8 Post 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.
ImageImageImage
ImageImageImage
ImageImageImage

ezza
Developers
Developers
Posts: 109
Joined: 04 Apr 2008, 09:50

Re: An Overall Macro Plugins Diff

#9 Post 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...

Darki
Been there done that!
Been there done that!
Posts: 143
Joined: 25 Oct 2008, 08:14
Noob?: No
Location: Spain, Madrid
Contact:

Re: An Overall Macro Plugins Diff

#10 Post 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. -.-
ImageImageImage
ImageImageImage
ImageImageImage

Locked