Henrybk

New Macro v1 beta patch

Feb 6th, 2016
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 107.00 KB | None | 0 0
  1. Index: macro.pl
  2. ===================================================================
  3. --- macro.pl    (revision 8992)
  4. +++ macro.pl    (working copy)
  5. @@ -21,10 +21,17 @@
  6.  use Translation qw/T TF/;
  7.  use lib $Plugins::current_plugin_folder;
  8.  use Macro::Data;
  9. +use Macro::Utilities qw(callMacro);
  10. +use Macro::Plugin;
  11. +use Macro::Lists;
  12. +use Macro::Lists::Automacro;
  13. +use Macro::Lists::Condition;
  14. +use Macro::Lists::Macro;
  15. +use Macro::Parser;
  16. +use Macro::FileParser;
  17.  use Macro::Script;
  18. -use Macro::Parser qw(parseMacroFile);
  19. -use Macro::Automacro qw(automacroCheck consoleCheckWrapper releaseAM);
  20. -use Macro::Utilities qw(callMacro);
  21. +use Macro::Automacro;
  22. +use Macro::Macro;
  23.  
  24.  #########
  25.  # startup
  26. @@ -38,8 +45,7 @@
  27.  my $chooks = Commands::register(
  28.     ['macro', "Macro plugin", \&commandHandler]
  29.  );
  30. -my $autohooks;
  31. -my $loghook;
  32. +
  33.  my $cfID;
  34.  my $macro_file;
  35.  
  36. @@ -48,29 +54,11 @@
  37.     my (undef, $args) = @_;
  38.     if ($args->{key} eq 'macro_file') {
  39.         Settings::removeFile($cfID);
  40. -       $cfID = Settings::addControlFile($args->{val}, loader => [ \&parseAndHook, \%macro]);
  41. +       $cfID = Settings::addControlFile($args->{val}, loader => [ \&parseAndHook]);
  42.         Settings::loadByHandle($cfID);
  43.     }
  44.  }
  45.  
  46. -# onstart3
  47. -sub onstart3 {
  48. -   &checkConfig;
  49. -   $cfID = Settings::addControlFile($macro_file,loader => [\&parseAndHook,\%macro], mustExist => 0);
  50. -   Settings::loadByHandle($cfID);
  51. -  
  52. -   if (
  53. -       $interface->isa ('Interface::Wx')
  54. -       && $interface->{viewMenu}
  55. -       && $interface->can ('addMenu')
  56. -       && $interface->can ('openWindow')
  57. -   ) {
  58. -       $interface->addMenu ($interface->{viewMenu}, T('Macro debugger'), sub {
  59. -           $interface->openWindow (T('Macro'), 'Macro::Wx::Debugger', 1);
  60. -       }, T('Interactive debugger for macro plugin'));
  61. -   }
  62. -}
  63. -
  64.  # onReload
  65.  sub Reload {
  66.     message "macro plugin reloading, ", 'success';
  67. @@ -89,59 +77,28 @@
  68.  sub cleanup {
  69.     message "cleaning up\n", 'success';
  70.     Settings::removeFile($cfID) if defined $cfID;
  71. -   Log::delHook($loghook);
  72. -   foreach (@{$autohooks}) {Plugins::delHook($_)}
  73. -   undef $autohooks;
  74. -   undef $queue;
  75. -   undef %macro;
  76. -   undef %automacro;
  77. -   undef %varStack
  78. -}
  79. -
  80. -# onFile(Re)load
  81. -sub parseAndHook {
  82. -   my $file = shift;
  83. -   if (parseMacroFile($file, 0)) {
  84. -       Plugins::callHook ('macro/parseAndHook');
  85. -       &hookOnDemand; return 1
  86. +   if (defined $macroPlugin) {
  87. +       $macroPlugin->cleanHooks();
  88.     }
  89. -   error "error loading $file.\n";
  90. -   return 0
  91. +   undef $macroPlugin;
  92.  }
  93.  
  94. -# only adds hooks that are needed
  95. -sub hookOnDemand {
  96. -   foreach (@{$autohooks}) {Plugins::delHook($_)}
  97. -   undef $autohooks;
  98. -   Log::delHook($loghook) if defined $loghook;
  99. -   my %load = ('AI_pre' => 1);
  100. -   my $hookToLog;
  101. -   foreach my $a (keys %automacro) {
  102. -       next if $automacro{$a}->{disabled};
  103. -       if (defined $automacro{$a}->{spell}) {
  104. -           if (!defined $load{'is_casting'}) {$load{'is_casting'} = 1}
  105. -           if (!defined $load{'packet_skilluse'}) {$load{'packet_skilluse'} = 1}
  106. -       }
  107. -       if (defined $automacro{$a}->{areaSpell} && !defined $load{'packet_areaSpell'}) {$load{'packet_areaSpell'} = 1}
  108. -       if (defined $automacro{$a}->{pm} && !defined $load{'packet_privMsg'}) {$load{'packet_privMsg'} = 1}
  109. -       if (defined $automacro{$a}->{pubm} && !defined $load{'packet_pubMsg'}) {$load{'packet_pubMsg'} = 1}
  110. -       if (defined $automacro{$a}->{system} && !defined $load{'packet_sysMsg'}) {$load{'packet_sysMsg'} = 1;}
  111. -       if (defined $automacro{$a}->{party} && !defined $load{'packet_partyMsg'}) {$load{'packet_partyMsg'} = 1}
  112. -       if (defined $automacro{$a}->{guild} && !defined $load{'packet_guildMsg'}) {$load{'packet_guildMsg'} = 1}
  113. -       if (defined $automacro{$a}->{mapchange} && !defined $load{'packet_mapChange'}) {$load{'packet_mapChange'} = 1}
  114. -       if (defined $automacro{$a}->{hook} && !defined $load{$automacro{$a}->{hook}}) {$load{$automacro{$a}->{hook}} = 1}
  115. -       if (defined $automacro{$a}->{console} && !defined $hookToLog) {$hookToLog = 1}
  116. -       if (defined $automacro{$a}->{playerguild} && !defined $load{'player'}) {$load{'player'} = 1}
  117. -       if (defined $automacro{$a}->{playerguild} && !defined $load{'charNameUpdate'}) {$load{'charNameUpdate'} = 1}
  118. +# onstart3
  119. +sub onstart3 {
  120. +   &checkConfig;
  121. +   $cfID = Settings::addControlFile($macro_file,loader => [\&parseAndHook], mustExist => 0);
  122. +   Settings::loadByHandle($cfID);
  123. +  
  124. +   if (
  125. +       $interface->isa ('Interface::Wx')
  126. +       && $interface->{viewMenu}
  127. +       && $interface->can ('addMenu')
  128. +       && $interface->can ('openWindow')
  129. +   ) {
  130. +       $interface->addMenu ($interface->{viewMenu}, T('Macro debugger'), sub {
  131. +           $interface->openWindow (T('Macro'), 'Macro::Wx::Debugger', 1);
  132. +       }, T('Interactive debugger for macro plugin'));
  133.     }
  134. -   foreach my $l (keys %load) {
  135. -       message "[macro] hooking to $l\n";
  136. -       push(@{$autohooks}, Plugins::addHook($l, \&automacroCheck))
  137. -   }
  138. -   if ($hookToLog) {
  139. -       message "[macro] hooking to log\n";
  140. -       $loghook = Log::addHook(\&consoleCheckWrapper)
  141. -   }
  142.  }
  143.  
  144.  # checks macro configuration
  145. @@ -154,9 +111,30 @@
  146.         configModify('macro_orphans', 'terminate')
  147.     }
  148.  
  149. -   return 1
  150. +   return 1;
  151.  }
  152.  
  153. +# onFile(Re)load
  154. +sub parseAndHook {
  155. +   my $file = shift;
  156. +   if (defined $macroPlugin) {
  157. +       $macroPlugin->reload();
  158. +   } else {
  159. +       $macroPlugin = new Macro::Plugin();
  160. +   }
  161. +  
  162. +  
  163. +   if (parseMacroFile($file, 0)) {
  164. +       Plugins::callHook ('macro/parseAndHook');
  165. +      
  166. +       $macroPlugin->hookOnDemand();
  167. +      
  168. +       return 1;
  169. +   }
  170. +   error "error loading $file.\n";
  171. +   return 0
  172. +}
  173. +
  174.  # macro command handler
  175.  sub commandHandler {
  176.     ### no parameter given
  177. @@ -176,61 +154,48 @@
  178.     ### parameter: list
  179.     if ($arg eq 'list') {
  180.         message(sprintf("The following macros are available:\n%smacros%s\n","-"x10,"-"x9), "list");
  181. -       foreach my $m (keys %macro) {message "$m\n" unless $m =~ /^tempMacro/}
  182. +       foreach my $macro (@{$macroPlugin->{macro}->getItems()}) {message $macro->{name}."\n"}
  183.         message(sprintf("%sautomacros%s\n", "-"x8, "-"x7), "list");
  184. -       foreach my $a (sort {
  185. -           ($automacro{$a}->{priority} or 0) <=> ($automacro{$b}->{priority} or 0)
  186. -       } keys %automacro) {message "$a\n"}
  187. +       foreach my $automacro (@{$macroPlugin->{automacro}->getItems()}) {message $automacro->{name}."\n"}
  188.         message(sprintf("%sPerl Sub%s\n", "-"x9, "-"x8), "list");
  189.         foreach my $s (@perl_name) {message "$s\n"}
  190.         message(sprintf("%s\n","-"x25), "list");
  191.     ### parameter: status
  192.     } elsif ($arg eq 'status') {
  193. -       if (defined $queue) {
  194. -           message(sprintf("macro %s\n", $queue->name), "list");
  195. -           message(sprintf("status: %s\n", $queue->registered?"running":"waiting"));
  196. -           my %tmp = $queue->timeout;
  197. +       if ($macroPlugin->isOnQueue()) {
  198. +           message(sprintf("macro %s\n", $macroPlugin->{queue}->name), "list");
  199. +           message(sprintf("status: %s\n", $macroPlugin->{queue}->registered?"running":"waiting"));
  200. +           my %tmp = $macroPlugin->{queue}->timeout;
  201.             message(sprintf("delay: %ds\n", $tmp{timeout}));
  202. -           message(sprintf("line: %d\n", $queue->line));
  203. -           message(sprintf("override AI: %s\n", $queue->overrideAI?"yes":"no"));
  204. -           message(sprintf("paused: %s\n", $onHold?"yes":"no"));
  205. -           message(sprintf("finished: %s\n", $queue->finished?"yes":"no"));
  206. +           message(sprintf("line: %d\n", $macroPlugin->{queue}->line));
  207. +           message(sprintf("override AI: %s\n", $macroPlugin->{queue}->overrideAI?"yes":"no"));
  208. +           message(sprintf("paused: %s\n", $macroPlugin->isPaused()?"yes":"no"));
  209. +           message(sprintf("finished: %s\n", $macroPlugin->{queue}->finished?"yes":"no"));
  210.         } else {
  211.             message "There's no macro currently running.\n"
  212.         }
  213.     ### parameter: stop
  214.     } elsif ($arg eq 'stop') {
  215. -       undef $queue;
  216. -       message "macro queue cleared.\n"
  217. +       $macroPlugin->clearQueue();
  218.     ### parameter: pause
  219.     } elsif ($arg eq 'pause') {
  220. -       if (defined $queue) {
  221. -           $onHold = 1;
  222. -           message "macro ".$queue->name." paused.\n"
  223. -       } else {
  224. -           warning "There's no macro currently running.\n"
  225. -       }
  226. +       $macroPlugin->pauseMacro();
  227.     ### parameter: resume
  228.     } elsif ($arg eq 'resume') {
  229. -       if (defined $queue) {
  230. -           $onHold = 0;
  231. -           message "macro ".$queue->name." resumed.\n"
  232. -       } else {
  233. -           warning "There's no macro currently running.\n"
  234. -       }
  235. +       $macroPlugin->resumeMacro();
  236.     ### parameter: reset
  237. -   } elsif ($arg eq 'reset') {
  238. -       if (!defined $params[0]) {
  239. -           foreach my $am (keys %automacro) {undef $automacro{$am}->{disabled}}
  240. -           message "automacro runonce list cleared.\n";
  241. -           return
  242. -       }
  243. -       for my $reset (@params) {
  244. -           my $ret = releaseAM($reset);
  245. -           if ($ret == 1)    {message "automacro $reset reenabled.\n"}
  246. -           elsif ($ret == 0) {warning "automacro $reset wasn't disabled.\n"}
  247. -           else              {error "automacro $reset not found.\n"}
  248. -       }
  249. +   #} elsif ($arg eq 'reset') {
  250. +   #   if (!defined $params[0]) {
  251. +   #       foreach my $am (keys %automacro) {undef $automacro{$am}->{disabled}}
  252. +   #       message "automacro runonce list cleared.\n";
  253. +   #       return
  254. +   #   }
  255. +   #   for my $reset (@params) {
  256. +   #       my $ret = releaseAM($reset);
  257. +   #       if ($ret == 1)    {message "automacro $reset reenabled.\n"}
  258. +   ##      elsif ($ret == 0) {warning "automacro $reset wasn't disabled.\n"}
  259. +   #       else              {error "automacro $reset not found.\n"}
  260. +   #   }
  261.     ### parameter: version
  262.     } elsif ($arg eq 'version') {
  263.         message "macro plugin version $Version\n", "list";
  264. @@ -243,12 +208,12 @@
  265.     ### debug
  266.     } elsif ($arg eq 'varstack') {
  267.         message "Varstack List\n", "menu";
  268. -       foreach my $v (keys %varStack) {
  269. -           message "\$varStack{$v} = [".$varStack{$v}."]\n", "menu"
  270. +       foreach my $v (keys %{$macroPlugin->{macroVars}}) {
  271. +           message "\$macroPlugin->{macroVars}{$v} = [".$macroPlugin->{macroVars}{$v}."]\n", "menu"
  272.         }
  273.     ### parameter: probably a macro
  274.     } else {
  275. -       if (defined $queue) {
  276. +       if ($macroPlugin->isOnQueue()) {
  277.             warning "a macro is already running. Wait until the macro has finished or call 'macro stop'\n";
  278.             return
  279.         }
  280. @@ -263,24 +228,23 @@
  281.             if ($params[$idx] =~ /^--/) {$cparms = substr(join(' ', map { "$_" } @params), 2); last}
  282.         }
  283.        
  284. -       delete $varStack{$_} for grep /^\.param\d+$/, keys %varStack;
  285. +       $macroPlugin->deleteVar($_) for grep /^\.param\d+$/, keys %{$macroPlugin->{macroVars}};
  286.         if ($cparms) {
  287.             #parse macro parameters
  288.             my @new_params = $cparms =~ /"[^"]+"|\S+/g;
  289.             foreach my $p (1..@new_params) {
  290. -               $varStack{".param".$p} = $new_params[$p-1];
  291. -               $varStack{".param".$p} = substr($varStack{".param".$p}, 1, -1) if ($varStack{".param".$p} =~ /^".*"$/); # remove quotes
  292. +               $macroPlugin->setVarValue(".param".$p,$new_params[$p-1]);
  293. +               $macroPlugin->setVarValue(".param".$p,substr($macroPlugin->getVar(".param".$p), 1, -1)) if ($macroPlugin->getVar(".param".$p) =~ /^".*"$/);
  294.             }
  295.         }
  296.        
  297. -       $queue = new Macro::Script($arg, $repeat);
  298. -       if (!defined $queue) {error "macro $arg not found or error in queue\n"}
  299. +       $macroPlugin->{queue} = new Macro::Script($arg, $repeat);
  300. +       if (!defined $macroPlugin->{queue}) {error "macro $arg not found or error in queue\n"}
  301.         else {
  302. -           $onHold = 0;
  303. -           if ($oAI) {$queue->overrideAI(1)}
  304. -           if ($exclusive) {$queue->interruptible(0)}
  305. -           if (defined $mdelay) {$queue->setMacro_delay($mdelay)}
  306. -           if (defined $orphan) {$queue->orphan($orphan)}
  307. +           if ($oAI) {$macroPlugin->{queue}->overrideAI(1)}
  308. +           if ($exclusive) {$macroPlugin->{queue}->interruptible(0)}
  309. +           if (defined $mdelay) {$macroPlugin->{queue}->setMacro_delay($mdelay)}
  310. +           if (defined $orphan) {$macroPlugin->{queue}->orphan($orphan)}
  311.         }
  312.     }
  313.  }
  314. Index: Macro/Automacro.pm
  315. ===================================================================
  316. --- Macro/Automacro.pm  (revision 8992)
  317. +++ Macro/Automacro.pm  (working copy)
  318. @@ -1,827 +1,83 @@
  319. -# $Id: Automacro.pm r6760 2009-07-06 02:23:00Z ezza $
  320.  package Macro::Automacro;
  321.  
  322.  use strict;
  323.  
  324. -require Exporter;
  325. -our @ISA = qw(Exporter);
  326. -our @EXPORT_OK = qw(releaseAM lockAM automacroCheck consoleCheckWrapper);
  327. -our @EXPORT = qw(checkLocalTime checkVar checkVarVar checkLoc checkPersonGuild checkLevel checkLevel checkClass
  328. -   checkPercent checkStatus checkItem checkPerson checkCond checkCast checkGround checkSpellsID
  329. -   checkEquip checkMsg checkMonster checkAggressives checkConsole checkMapChange);
  330. -  
  331. -use Misc qw(whenGroundStatus getSpellName getActorName);
  332. -use Utils;
  333. -use Globals;
  334. -use Skill;
  335. -use AI;
  336. -use Log qw(message error warning);
  337. -use Macro::Data;
  338. -use Macro::Utilities qw(between cmpr match getArgs refreshGlobal
  339. -   getPlayerID getSoldOut getInventoryAmount getCartAmount getShopAmount
  340. -   getStorageAmount callMacro sameParty);
  341. -
  342. -our ($rev) = q$Revision: 6760 $ =~ /(\d+)/;
  343. -
  344. -# check for variable #######################################
  345. -sub checkVar {
  346. -   my ($var, $cond, $val) = getArgs($_[0]);
  347. -
  348. -   $var = "#$var" if $_[1] eq 'varvar';
  349. -
  350. -   if ($cond eq "unset") {return exists $varStack{$var}?0:1}
  351. -
  352. -   # TODO: seems like this is not needed, because automacroCheck does it
  353. -   # and refreshGlobal ignores args
  354. -   refreshGlobal($var);
  355. -
  356. -   if (exists $varStack{$var}) {return cmpr($varStack{$var}, $cond, $val)}
  357. -   else {return $cond eq "!="}
  358. +sub new {
  359. +   my ($class, $name, $conditions, $parameters) = @_;
  360. +   my $self = {
  361. +       name => $name,
  362. +       listIndex => -1
  363. +   };
  364. +   bless $self, $class;
  365. +   $self->setParameters($parameters);
  366. +   $self->createConditionList($conditions);
  367. +   return $self;
  368.  }
  369.  
  370. -# check for ground statuses
  371. -sub checkGround {
  372. -   my $arg = $_[0];
  373. -   my $not = ($arg =~ s/^not +//)?1:0;
  374. -  
  375. -   if (whenGroundStatus(calcPosition($char), $arg)) {return $not?0:1}
  376. -   return $not?1:0
  377. -}
  378. -
  379. -# checks for location ######################################
  380. -# parameter: map [x1 y1 [x2 y2]]
  381. -# note: when looking in the default direction (north)
  382. -# x1 < x2 and y1 > y2 where (x1|y1)=(upper left) and
  383. -#                           (x2|y2)=(lower right)
  384. -# uses: calcPosition (Utils?)
  385. -sub checkLoc {
  386. -   my $arg = $_[0];
  387. -   if ($arg =~ /,/) {
  388. -       my @locs = split(/\s*,\s*/, $arg);
  389. -       foreach my $l (@locs) {return 1 if checkLoc($l)}
  390. -       return 0
  391. +sub isActive {
  392. +   my ($self) = @_;
  393. +   if (exists $self->{disabled}) {
  394. +       return 0 if ($self->{disabled});
  395.     }
  396. -   my $not = ($arg =~ s/^not +//)?1:0;
  397. -   my ($map, $x1, $y1, $x2, $y2) = split(/ /, $arg);
  398. -   if ($map =~ /^\s*\$/) {
  399. -       my ($var) = $map =~ /^\$([a-zA-Z][a-zA-Z\d]*)\s*$/;
  400. -       return 0 unless defined $var;
  401. -       return 0 unless exists $varStack{$var};
  402. -       $map = $varStack{$var}
  403. -   }
  404. -   if ($map eq $field->baseName || $map eq $field->name) {
  405. -       if ($x1 && $y1) {
  406. -           my $pos = calcPosition($char);
  407. -           return 0 unless defined $pos->{x} && defined $pos->{y};
  408. -           if ($x2 && $y2) {
  409. -               if (between($x1, $pos->{x}, $x2) && between($y2, $pos->{y}, $y1)) {
  410. -                   return $not?0:1
  411. -               }
  412. -               return $not?1:0
  413. -           }
  414. -           if ($x1 == $pos->{x} && $y1 == $pos->{y}) {
  415. -               return $not?0:1
  416. -           }
  417. -           return $not?1:0
  418. -       }
  419. -       return $not?0:1
  420. -   }
  421. -   return $not?1:0
  422. +   return 1;
  423.  }
  424.  
  425. -# check for pc local time
  426. -sub checkLocalTime {
  427. -   my ($cond, $val) = $_[0] =~ /^\s*([<>=!]+)\s+(\$[a-zA-Z][a-zA-Z\d]*|\d{2}:\d{2}(?::\d{2})?)\s*$/;
  428. -   return 0 if !defined $cond || !defined $val;
  429. -   my ($time, $hr, $min, $sec);
  430. -   if ($val =~ /^\$/) {
  431. -       my ($var) = $val =~ /^\$([a-zA-Z][a-zA-Z\d]*)\s*$/;
  432. -       if (exists $varStack{$var}) {$val = $varStack{$var}}
  433. -       else {return 0}
  434. -   }
  435. -   if ($val =~ /^\d{2}:\d{2}(?::\d{2})?\s*$/) {
  436. -       ($hr, $min, $sec) = split(/:/, $val, 3);
  437. -       $sec = 0 if !defined $sec;
  438. -   }
  439. -   else {message "Wrong time format: hh:mm:ss\n", "menu"; return 0}
  440. -   $time = $hr * 3600 + $min * 60 + $sec;
  441. -   my ($lc_sec, $lc_min, $lc_hr) = localtime;
  442. -   my $lc_time = $lc_hr * 3600 + $lc_min * 60 + $lc_sec;
  443. -
  444. -   return cmpr($lc_time, $cond, $time)?1:0;
  445. +sub getParameter {
  446. +   my ($self, $parameter) = @_;
  447. +   return $self->{parameters}{$parameter} if (exists $self->{parameters}{$parameter});
  448. +   return undef;
  449.  }
  450.  
  451. -# check for ($playersList guild) vs (guild.txt or guild list)
  452. -sub checkPersonGuild {
  453. -   my ($guild, $trigger, $arg) = @_;
  454. -   return 0 if !defined $guild || !defined $trigger || !defined $arg;
  455. -  
  456. -   my $actor = $arg->{player};
  457. -  
  458. -   return 0 unless defined $actor->{guild};
  459. -   my $guildName = $actor->{guild}{name};
  460. -   my $dist = $config{clientSight};
  461. -
  462. -   my $not = 0;
  463. -   if ($guild =~ /^not\s+/) {$not = 1; $guild =~ s/^not +//g}
  464. -   if ($guild =~ /(^.*),\s*(\d+)\s*$/) {$guild = $1; $dist = $2}
  465. -  
  466. -   return 0 unless (distance(calcPosition($char), calcPosition($actor)) <= $dist);
  467. -  
  468. -   $varStack{".lastPlayerID"} = undef;
  469. -   $varStack{".lastGuildName"} = undef;
  470. -   $varStack{".lastGuildNameBinID"} = undef;
  471. -   $varStack{".lastGuildNameBinIDDist"} = undef;
  472. -   $varStack{".lastGuildNameBinIDName"} = undef;
  473. -   $varStack{".lastGuildNameBinIDJobName"} = undef;
  474. -
  475. -   if ($guild eq 'guild.txt') {
  476. -       my @gld;
  477. -       if (open(FILE, "<", Settings::getControlFilename("guild.txt"))) {
  478. -           while (<FILE>) {
  479. -               $_ =~ s/\x{FEFF}//g;
  480. -               chomp($_);
  481. -               next if ($_ =~ /^[\n\r#]/);
  482. -               $_ =~ s/  +$/ /; $_ =~ s/^  +/ /;
  483. -               push @gld, $_;
  484. -           }
  485. -           close FILE;
  486. -           }
  487. -           if (@gld) {$guild = join(' , ', @gld)}
  488. -           else {$guild = ''}
  489. -        }
  490. -        
  491. -   if (defined $guild && existsInList($guild, $guildName)) {
  492. -       return 0 if $not;
  493. -       $varStack{".lastPlayerID"} = unpack("V1", $actor->{ID});
  494. -       $varStack{".lastGuildName"} = $guildName;
  495. -       $varStack{".lastGuildNameBinID"} = $actor->{binID};
  496. -       $varStack{".lastGuildNameBinIDDist"} = sprintf("%.1f", distance(calcPosition($char), calcPosition($actor)));
  497. -       $varStack{".lastGuildNameBinIDName"} = $actor->{name};
  498. -       $varStack{".lastGuildNameBinIDJobName"} = $jobs_lut{$actor->{jobID}};
  499. -       return 1
  500. +sub setParameters {
  501. +   my ($self, $parameters) = @_;
  502. +   my ($key,$value);
  503. +   foreach (keys %{$parameters}) {
  504. +       $key = $_;
  505. +       $value = $parameters->{$_};
  506. +       $self->{parameters}{$key} = $value;
  507. +   } continue {
  508. +       undef $key;
  509. +       undef $value;
  510.     }
  511. -   elsif (defined $guild && $not) {
  512. -       $varStack{".lastPlayerID"} = unpack("V1", $actor->{ID});
  513. -       $varStack{".lastGuildName"} = $guildName;
  514. -       $varStack{".lastGuildNameBinID"} = $actor->{binID};
  515. -       $varStack{".lastGuildNameBinIDDist"} = sprintf("%.1f", distance(calcPosition($char), calcPosition($actor)));
  516. -       $varStack{".lastGuildNameBinIDName"} = $actor->{name};
  517. -       $varStack{".lastGuildNameBinIDJobName"} = $jobs_lut{$actor->{jobID}};
  518. -       return 1;
  519. +   if (!defined $self->{parameters}{priority})  {
  520. +       $self->{parameters}{priority} = 0;
  521.     }
  522. -
  523. -   return 0
  524.  }
  525.  
  526. -# checks for base/job level ################################
  527. -# uses cmpr (Macro::Utils)
  528. -sub checkLevel {
  529. -   my ($cond, $level) = $_[0] =~ /([<>=!]+)\s+(\$[a-zA-Z][a-zA-Z\d]*|\d+|\d+\s*\.{2}\s*\d+)\s*$/;
  530. -   if ($level =~ /^\s*\$/) {
  531. -       my ($var) = $level =~ /^\$([a-zA-Z][a-zA-Z\d]*)\s*$/;
  532. -       return 0 unless defined $var;
  533. -       if (exists $varStack{$var}) {$level = $varStack{$var}}
  534. -       else {return 0}
  535. -   }
  536. -   return cmpr($char->{$_[1]}, $cond, $level)
  537. -}
  538. -
  539. -# checks for player's jobclass #############################
  540. -sub checkClass {
  541. -   return 0 unless defined $char;
  542. -   my $class = $_[0];
  543. -   if ($class =~ /^\s*\$/) {
  544. -       my ($var) = $class =~ /^\$([a-zA-Z][a-zA-Z\d]*)\s*$/;
  545. -       return 0 unless defined $var;
  546. -       if (exists $varStack{$var}) {$class = $varStack{$var}}
  547. -       else {return 0}
  548. -   }
  549. -   return lc($class) eq lc($::jobs_lut{$char->{jobID}})?1:0
  550. -}
  551. -
  552. -# checks for HP/SP/Weight ##################################
  553. -# uses cmpr (Macro::Utils)
  554. -sub checkPercent {
  555. -   my ($arg, $what) = @_;
  556. -   my ($cond, $amount) = $arg =~ /([<>=!]+)\s+(\$[a-zA-Z][a-zA-Z\d]*%?|\d+%?|\d+\s*\.{2}\s*\d+%?)\s*$/;
  557. -   if ($what =~ /^(?:hp|sp|weight)$/) {
  558. -       return 0 unless (defined $char && defined $char->{$what} && defined $char->{$what."_max"});
  559. -       if ($amount =~ /^\s*(?:\d+|\d+\s*\.{2}\s*\d+)%$/ && $char->{$what."_max"}) {
  560. -           $amount =~ s/%$//;
  561. -           return cmpr(($char->{$what} / $char->{$what."_max"} * 100), $cond, $amount)
  562. -       }
  563. -       elsif ($amount =~ /^\s*\$/) {
  564. -           my ($var, $percent) = $amount =~ /^\$([a-zA-Z][a-zA-Z\d]*)(%)?\s*/;
  565. -           return 0 unless defined $var;
  566. -           if ((defined $percent || $percent eq "%") && defined $char->{$what."_max"}) {
  567. -               if (exists $varStack{$var}) {
  568. -                   $amount = $varStack{$var};
  569. -                   return cmpr(($char->{$what} / $char->{$what."_max"} * 100), $cond, $amount)
  570. -               }
  571. -           } else {
  572. -               if (exists $varStack{$var}) {
  573. -                   $amount = $varStack{$var};
  574. -                   return cmpr($char->{$what}, $cond, $amount)
  575. -               }
  576. +sub createConditionList {
  577. +   my ($self, $conditions) = @_;
  578. +   $self->{conditionList} = new Macro::Lists::Condition();
  579. +   my $cond;
  580. +   my ($module,@conditionsText);
  581. +   foreach (keys %{$conditions}) {
  582. +       $module = $_;
  583. +       @conditionsText = @{$conditions->{$_}};
  584. +       eval "use $module";
  585. +       foreach my $newConditionText (@conditionsText) {
  586. +           $cond = $module->new($newConditionText);
  587. +           $self->{conditionList}->add($cond);
  588. +           foreach my $hook (@{$cond->{hooks}}) {
  589. +               push (@{$self->{hooks}{$hook}}, $cond->{listIndex});
  590.             }
  591. -       }
  592. -       else {return cmpr($char->{$what}, $cond, $amount)}
  593. -   }
  594. -   elsif ($what eq 'cweight') {
  595. -       return 0 unless (defined $cart{weight} && defined $cart{weight_max});
  596. -       if ($amount =~ /^\s*(?:\d+|\d+\s*\.{2}\s*\d+)%$/ && $cart{weight_max}) {
  597. -           $amount =~ s/%$//;
  598. -           return cmpr(($cart{weight} / $cart{weight_max} * 100), $cond, $amount)
  599. -       }
  600. -       elsif ($amount =~ /^\s*\$/) {
  601. -           my ($var, $percent) = $amount =~ /^\$([a-zA-Z][a-zA-Z\d]*)(%)?\s*/;
  602. -           return 0 unless defined $var;
  603. -           if ((defined $percent || $percent eq "%") && defined $cart{weight_max}) {
  604. -               if (exists $varStack{$var}) {
  605. -                   $amount = $varStack{$var};
  606. -                   return cmpr(($cart{weight} / $cart{weight_max} * 100), $cond, $amount)
  607. -               }
  608. -           } else {
  609. -               if (exists $varStack{$var}) {
  610. -                   $amount = $varStack{$var};
  611. -                   return cmpr($cart{weight}, $cond, $amount)
  612. -               }
  613. +           foreach my $variable (@{$cond->{variables}}) {
  614. +               push (@{$self->{variables}{$variable}}, $cond->{listIndex});
  615.             }
  616. +       } continue {
  617. +           undef $cond;
  618.         }
  619. -       else {return cmpr($cart{weight}, $cond, $amount)}
  620. +   } continue {
  621. +       undef $module;
  622. +       undef @conditionsText;
  623.     }
  624. -   return 0
  625.  }
  626.  
  627. -# checks for status #######################################
  628. -sub checkStatus {
  629. -   if ($_[0] =~ /,/) {
  630. -       my @statuses = split(/\s*,\s*/, $_[0]);
  631. -       foreach my $s (@statuses) {return 1 if checkStatus($s)}
  632. -       return 0
  633. +sub check {
  634. +   my ($self) = @_;
  635. +   return 0 if (defined $self->{disabled} && !$self->{disabled});
  636. +   foreach my $condition (@{$self->{conditionList}->getItems()}) {
  637. +       return 0 if (!$condition->isTrue());
  638.     }
  639. -
  640. -   my $status = $_[0];
  641. -   return ($status =~ s/^not +//i xor $char->statusActive($status)) if defined $char;
  642. +   return 1;
  643.  }
  644.  
  645. -# checks for item conditions ##############################
  646. -# uses: getInventoryAmount, getCartAmount, getShopAmount,
  647. -#       getStorageAmount (Macro::Utils?)
  648. -sub checkItem {
  649. -   my ($where, $check) = @_;
  650. -   if ($check =~ /,/) {
  651. -       my @checks = split(/\s*,\s*/, $check);
  652. -       foreach my $c (@checks) {return 1 if checkItem($where, $c)}
  653. -       return 0
  654. -   }
  655. -   my ($item, $cond, $amount) = getArgs($check);
  656. -   if ($item =~ /^\$/) {
  657. -       my ($var) = $item =~ /^\$([a-zA-Z][a-zA-Z\d]*)\s*/;
  658. -       return 0 unless defined $var;
  659. -       if (exists $varStack{$var}) {$item = $varStack{$var}}
  660. -       else {return 0}
  661. -   }
  662. -   if ($amount =~ /^\$/) {
  663. -       my ($var1) = $amount =~ /^\$([a-zA-Z][a-zA-Z\d]*)\s*/;
  664. -       return 0 unless defined $var1;
  665. -       if (exists $varStack{$var1}) {$amount = $varStack{$var1}}
  666. -       else {return 0}
  667. -   }
  668. -   my $what;
  669. -   if ($where eq 'inv')  {$what = getInventoryAmount($item)}
  670. -   if ($where eq 'cart') {$what = getCartAmount($item)}
  671. -   if ($where eq 'inv')  {return 0 unless (time > $ai_v{'inventory_time'}); $what = getInventoryAmount($item);};
  672. -   if ($where eq 'cart') {return 0 unless (time > $ai_v{'cart_time'}); $what = getCartAmount($item)};
  673. -   if ($where eq 'shop') {return 0 unless $shopstarted; $what = getShopAmount($item)}
  674. -   if ($where eq 'stor') {return 0 unless $::storage{opened}; $what = getStorageAmount($item)}
  675. -
  676. -   return cmpr($what, $cond, $amount)?1:0
  677. -}
  678. -
  679. -# checks for near person ##################################
  680. -sub checkPerson {
  681. -   my ($who, $dist) = $_[0] =~ /^(["\/].*?["\/]\w*)\s*,?\s*(.*)/;
  682. -
  683. -   foreach my $player (@{$playersList->getItems()}) {
  684. -       next unless match($player->name, $who);
  685. -       if ($dist > 0 && distance($char->{pos_to}, $player->{pos_to}) >= $dist) {
  686. -           return 0;
  687. -       }
  688. -       my $val = sprintf("%d %d %s", $player->{pos_to}{x}, $player->{pos_to}{y}, $field->baseName);
  689. -       $varStack{".lastPlayerName"} = $player->name;
  690. -       $varStack{".lastPlayerPos"} = $val;
  691. -       $varStack{".lastPlayerLevel"} = $player->{lv};
  692. -       $varStack{".lastPlayerJob"} = $player->job;
  693. -       $varStack{".lastPlayerAccountId"} = $player->{nameID};
  694. -       $varStack{".lastPlayerBinId"} = $player->{binID};
  695. -       return 1
  696. -   }
  697. -   return 0
  698. -}
  699. -
  700. -# checks arg1 for condition in arg3 #######################
  701. -# uses: cmpr (Macro::Utils)
  702. -sub checkCond {
  703. -   my ($cond, $amount) = $_[1] =~ /([<>=!]+)\s+(\$[a-zA-Z][a-zA-Z\d]*|\d+|\d+\s*\.{2}\s*\d+)\s*$/;
  704. -   if ($amount =~ /^\s*\$/) {
  705. -       my ($var) = $amount =~ /^\$([a-zA-Z][a-zA-Z\d]*)\s*$/;
  706. -       return 0 unless defined $var;
  707. -       if (exists $varStack{$var}) {$amount = $varStack{$var}}
  708. -       else {return 0}
  709. -   }
  710. -   return cmpr($_[0], $cond, $amount)?1:0
  711. -}
  712. -
  713. -# checks for equipment ####################################
  714. -# equipped <item>, <item2>, ... # equipped item or item2 or ..
  715. -# equipped rightHand <item>, rightAccessory <item2>, ... # equipped <item> on righthand etc.
  716. -# equipped leftHand none, .. # equipped nothing on lefthand etc.
  717. -# see @Item::slots
  718. -sub checkEquip {
  719. -   if ($_[0] =~ /,/) {
  720. -       my @equip = split(/\s*,\s*/, $_[0]);
  721. -       foreach my $e (@equip) {return 1 if checkEquip($e)}
  722. -       return 0
  723. -   }
  724. -
  725. -   my $arg = $_[0];
  726. -
  727. -   if ($arg =~ m/^((?:top|mid|low)Head|(?:left|right)Hand|robe|armor|shoes|(?:left|right)Accessory|arrow)\s+(.*)/i) {
  728. -       if (my $item = $char->{equipment}{$1}) {
  729. -           return lc($2) eq lc($item->name)?1:0
  730. -       }
  731. -       return lc($2) eq 'none'?1:0
  732. -   }
  733. -
  734. -   $arg = lc($arg);
  735. -   foreach my $s (keys %{$char->{equipment}}) {
  736. -       next unless lc($char->{equipment}{$s}->name) eq $arg;
  737. -       return 1
  738. -   }
  739. -   return 0
  740. -}
  741. -
  742. -# checks for a spell casted on us/party members #########################
  743. -# uses: distance, judgeSkillArea (Utils?)
  744. -sub checkCast {
  745. -   my ($cast, $args) = @_;
  746. -   return 0 if $args->{sourceID} eq $accountID;
  747. -  
  748. -   $cast = lc($cast);
  749. -   my $party = ($cast =~ s/^party +//)?1:0;
  750. -   my $pos = calcPosition($char);
  751. -   my $target = (defined $args->{targetID})?$args->{targetID}:0;
  752. -   my $source = $args->{sourceID};
  753. -   return 0 if $target eq $source;
  754. -
  755. -   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()))) {
  756. -       if (my $actor = $monstersList->getByID($source)) {
  757. -           $varStack{".caster"} = "monster";
  758. -           $varStack{".casterName"} = $actor->{name};
  759. -           $varStack{".casterID"} = $actor->{binID};
  760. -           $varStack{".casterPos"} = $actor->{pos_to}{x} ." ". $actor->{pos_to}{y};
  761. -           $varStack{".casterDist"} = sprintf("%.1f", distance($pos, calcPosition($actor)))
  762. -
  763. -       }
  764. -       elsif (my $actor = $playersList->getByID($source)) {
  765. -           $varStack{".caster"} = "player";
  766. -           $varStack{".casterName"} = (defined $actor->{name})?$actor->{name}:"Unknown";
  767. -           $varStack{".casterID"} = $actor->{binID};
  768. -           $varStack{".casterPos"} = $actor->{pos_to}{x} ." ". $actor->{pos_to}{y};
  769. -           $varStack{".casterDist"} = sprintf("%.1f", distance($pos, calcPosition($actor)));
  770. -
  771. -       }
  772. -       else {return 0}
  773. -       $varStack{".casterSkill"} = Skill->new(idn => $args->{skillID})->getName();
  774. -       $varStack{".casterTarget"} = $args->{x} ." ". $args->{y};
  775. -       $varStack{".casterTargetName"} = $char->{name};
  776. -       return 1
  777. -   }
  778. -   elsif ($party && existsInList($cast, lc(Skill->new(idn => $args->{skillID})->getName()))) {
  779. -       return 0 if !$char->{'party'} || !%{$char->{'party'}};
  780. -       if (my $actor = $monstersList->getByID($source)) {
  781. -           foreach my Actor::Player $player (@{$playersList->getItems()}) {
  782. -               next unless sameParty($player->{name});
  783. -               if ($target eq $player->{ID} || ($player->{pos_to}{x} == $args->{x} && $player->{pos_to}{y} == $args->{y}) || distance($player->{pos}, $args) <= judgeSkillArea($args->{skillID})) {
  784. -                   $varStack{".caster"} = "monster";
  785. -                   $varStack{".casterName"} = $actor->{name};
  786. -                   $varStack{".casterID"} = $actor->{binID};
  787. -                   $varStack{".casterPos"} = $actor->{pos_to}{x} ." ". $actor->{pos_to}{y};
  788. -                   $varStack{".casterSkill"} = Skill->new(idn => $args->{skillID})->getName();
  789. -                   $varStack{".casterTarget"} = $args->{x} ." ". $args->{y};
  790. -                   $varStack{".casterTargetName"} = $player->{name};
  791. -                   $varStack{".casterDist"} = sprintf("%.1f", distance($pos, calcPosition($actor)));
  792. -                   return 1
  793. -               }
  794. -           }
  795. -
  796. -       }
  797. -       elsif (my $actor = $playersList->getByID($source)) {
  798. -           return 0 if sameParty($actor->{name});
  799. -           foreach my Actor::Player $player (@{$playersList->getItems()}) {
  800. -               next unless sameParty($player->{name});
  801. -               if ($target eq $player->{ID} || ($player->{pos_to}{x} == $args->{x} && $player->{pos_to}{y} == $args->{y}) || distance($player->{pos}, $args) <= judgeSkillArea($args->{skillID})) {
  802. -                   $varStack{".caster"} = "player";
  803. -                   $varStack{".casterName"} = (defined $actor->{name})?$actor->{name}:"Unknown";
  804. -                   $varStack{".casterID"} = $actor->{binID};
  805. -                   $varStack{".casterPos"} = $actor->{pos_to}{x} ." ". $actor->{pos_to}{y};
  806. -                   $varStack{".casterSkill"} = Skill->new(idn => $args->{skillID})->getName();
  807. -                   $varStack{".casterTarget"} = $args->{x} ." ". $args->{y};
  808. -                   $varStack{".casterTargetName"} = $player->{name};
  809. -                   $varStack{".casterDist"} = sprintf("%.1f", distance($pos, calcPosition($actor)));
  810. -                   return 1
  811. -               }
  812. -           }
  813. -       }
  814. -       else {return 0}
  815. -   }
  816. -   else {return 0}
  817. -}
  818. -
  819. -# checks for public, private, party or guild message ######
  820. -# uses calcPosition, distance (Utils?)
  821. -sub checkMsg {
  822. -   my ($var, $tmp, $arg) = @_;
  823. -   my $msg;
  824. -   if ($var eq '.lastpub') {
  825. -       ($msg, my $distance) = $tmp =~ /^([\/"].*?[\/"]\w*)\s*,?\s*(\d*)/;
  826. -       if ($distance ne '') {
  827. -           my $mypos = calcPosition($char);
  828. -           my $pos = calcPosition($::players{$arg->{pubID}});
  829. -           return 0 unless distance($mypos, $pos) <= $distance
  830. -       }
  831. -   } elsif ($var eq '.lastpm') {
  832. -       ($msg, my $allowed) = $tmp =~ /^([\/"].*?[\/"]\w*)\s*,?\s*(.*)/;
  833. -       my $auth;
  834. -       if (!$allowed) {
  835. -           $auth = 1
  836. -       } else {
  837. -           my @tfld = split(/,/, $allowed);
  838. -           for (my $i = 0; $i < @tfld; $i++) {
  839. -               next unless defined $tfld[$i];
  840. -               $tfld[$i] =~ s/(?:^ +| +$)//g;
  841. -               if ($arg->{privMsgUser} eq $tfld[$i]) {$auth = 1; last}
  842. -           }
  843. -       }
  844. -       return 0 unless $auth
  845. -   } elsif ($var eq '.lastsys') {
  846. -       ($msg) = $tmp =~ /^([\/"].*?[\/"]\w*)\s*,?\s*(.*)/;
  847. -       chomp($msg);
  848. -   } else {
  849. -       $msg = $tmp
  850. -   }  
  851. -   $arg->{Msg} =~ s/[\r\n]*$//g;
  852. -   if (match($arg->{Msg},$msg)){
  853. -       $varStack{$var} = $arg->{MsgUser};
  854. -       $varStack{$var."Msg"} = $arg->{Msg};
  855. -       return 1
  856. -   }
  857. -   return 0
  858. -}
  859. -
  860. -# checks for area spell
  861. -sub checkSpellsID {
  862. -   my ($line, $args) = @_;
  863. -   my $dist = $config{clientSight} || 20;
  864. -   my ($list, $cond);
  865. -   if ($line =~ /^\s*(.*),?\s+([<>=!~]+)\s+(\d+|\d+\s*.{2}\s*\d+)\s*$/) {
  866. -       ($list, $cond, $dist) = ($1, $2, $3)
  867. -   }
  868. -   else {$list = $line; $cond = "<="}
  869. -  
  870. -   foreach (@spellsID) {
  871. -       my $spell = $spells{$_};
  872. -       my $type = getSpellName($spell->{type});
  873. -       my $dist1 = sprintf("%.1f",distance(calcPosition($char), calcPosition($spell)));
  874. -       my ($actor, $owner, $ID) = getActorName($spell->{sourceID}) =~ /^(\w+?)\s(.*?)\s\((\d+)\)\s*$/;
  875. -       if (existsInList($list, $type) &&
  876. -           $args->{x} eq $spell->{'pos'}{'x'} &&
  877. -           $args->{y} eq $spell->{'pos'}{'y'} &&
  878. -           $args->{sourceID} eq $spell->{sourceID}
  879. -       ) {
  880. -           $varStack{".areaName"} = $type;
  881. -           $varStack{".areaActor"} = $actor;
  882. -           $varStack{".areaSourceName"} = $owner;
  883. -           $varStack{".areaSourceID"} = $ID;
  884. -           $varStack{".areaPos"} = sprintf("%d %d %s", $spell->{'pos'}{'x'}, $spell->{'pos'}{'y'}, $field->baseName);
  885. -           $varStack{".areaDist"} = $dist1;
  886. -           return cmpr($dist1, $cond, $dist)
  887. -       }
  888. -   }
  889. -   return 0
  890. -}
  891. -
  892. -# checks for monster ...
  893. -sub checkMonster {
  894. -   my $line = $_[0];
  895. -   my $not = $_[1];
  896. -   my ($mercenary, $use, $monsterList, $cond);
  897. -   my $mondist = $config{clientSight} || 20;
  898. -
  899. -   if ($line =~ /^\s*(.*),?\s+([<>=!~]+)\s+(\d+|\d+\s*.{2}\s*\d+)\s*$/) {
  900. -       ($monsterList, $cond, $mondist) = ($1, $2, $3)
  901. -   } else {
  902. -       $monsterList = $line;
  903. -       $cond = "<="
  904. -   }
  905. -
  906. -   if (!$not && $monsterList =~ /^(not|mercenary)\s+(.*)\s*$/) {
  907. -       if ($1 eq "not") {$not = 1; $monsterList = $2}
  908. -       else {$mercenary = 1; $use = 1; $monsterList = $2}
  909. -   }
  910. -
  911. -   foreach (@monstersID) {
  912. -       next unless defined $_;
  913. -       if ($mercenary) {
  914. -           #Whose the mercenary's master,
  915. -           #update later ;p
  916. -           my $mypos = calcPosition($char);
  917. -           my $pos = calcPosition($monsters{$_});
  918. -           my $dist = sprintf("%.1f",distance($pos, $mypos));
  919. -           if (existsInList($monsterList, $monsters{$_}->{name}) && $dist < 3) {$use = 0; last}
  920. -       }
  921. -       elsif ($not) {
  922. -           next if existsInList($monsterList, $monsters{$_}->{name});
  923. -           my $mypos = calcPosition($char);
  924. -           my $pos = calcPosition($monsters{$_});
  925. -           my $dist = sprintf("%.1f",distance($pos, $mypos));
  926. -           my $val = sprintf("%d %d %s", $pos->{x}, $pos->{y}, $field->baseName);
  927. -           $varStack{".lastMonster"} = $monsters{$_}->{name};
  928. -           $varStack{".lastMonsterPos"} = $val;
  929. -           $varStack{".lastMonsterDist"} = $dist;
  930. -           $varStack{".lastMonsterID"} = $monsters{$_}->{binID};
  931. -           $varStack{".lastMonsterBinID"} = $monsters{$_}->{binType};
  932. -           return cmpr($dist, $cond, $mondist)
  933. -       } else {
  934. -           if (existsInList($monsterList, $monsters{$_}->{name})) {
  935. -               my $counter;
  936. -               my $mypos = calcPosition($char);
  937. -               my $pos = calcPosition($monsters{$_});
  938. -               my $dist = sprintf("%.1f", distance($mypos, $pos));
  939. -               my $val = sprintf("%d %d %s", $pos->{x}, $pos->{y}, $field->baseName);
  940. -               $varStack{".lastMonster"} = $monsters{$_}->{name};
  941. -               $varStack{".lastMonsterPos"} = $val;
  942. -               $varStack{".lastMonsterDist"} = $dist;
  943. -               $varStack{".lastMonsterID"} = $monsters{$_}->{binID};
  944. -               $varStack{".lastMonsterBinID"} = $monsters{$_}->{binType};
  945. -               for (my $i = 0; $i < @::monstersID; $i++) {
  946. -                   next if $::monstersID[$i] eq "";
  947. -                   my $monster = Actor::get($::monstersID[$i]);
  948. -                   if ($monster->name eq $monsters{$_}->{name}) {
  949. -                       if ($monster->{binID} eq $monsters{$_}->{binID}) {
  950. -                           $counter++;
  951. -                           next
  952. -                       } else {
  953. -                           my $monsToMonDist = sprintf("%.1f",distance($pos, $monster->{pos_to}));
  954. -                           $counter++ if $monsToMonDist < 12;
  955. -                           next
  956. -                       }
  957. -                   }
  958. -                   next
  959. -               }
  960. -               $varStack{".lastMonsterCount"} = $counter;
  961. -               return cmpr($dist, $cond, $mondist)
  962. -           }
  963. -       }
  964. -   }
  965. -   return 1 if ($use);
  966. -   return 0
  967. -}
  968. -
  969. -# checks for aggressives
  970. -sub checkAggressives {
  971. -   my ($cond, $amount) = $_[0] =~ /([<>=!]+)\s+(\$[a-zA-Z][a-zA-Z\d]*|\d+|\d+\s*\.{2}\s*\d+)\s*$/;
  972. -   if ($amount =~ /^\s*\$/) {
  973. -       my ($var) = $amount =~ /^\$([a-zA-Z][a-zA-Z\d]*)\s*$/;
  974. -       return 0 unless defined $var;
  975. -       if (exists $varStack{$var}) {$amount = $varStack{$var}}
  976. -       else {return 0}
  977. -   }
  978. -   return cmpr(scalar ai_getAggressives, $cond, $amount)
  979. -}
  980. -# checks for console message
  981. -sub checkConsole {
  982. -   my ($msg, $arg) = @_;
  983. -   $$arg[4] =~ s/[\r\n]*$//;
  984. -   if (match($$arg[4],$msg)){
  985. -       $varStack{".lastLogMsg"} = $$arg[4];
  986. -       return 1
  987. -   }
  988. -   return 0
  989. -}
  990. -
  991. -sub consoleCheckWrapper {
  992. -   return unless defined $conState;
  993. -   # skip "macro" and "cvsdebug" domains to avoid loops
  994. -   return if $_[1] =~ /^(?:macro|cvsdebug)$/;
  995. -   # skip debug messages unless macro_allowDebug is set
  996. -   return if ($_[0] eq 'debug' && !$::config{macro_allowDebug});
  997. -   my @args = @_;
  998. -   automacroCheck("log", \@args)
  999. -}
  1000. -
  1001. -# checks for map change
  1002. -sub checkMapChange {
  1003. -   return ($_[0] eq 'any' || $_[0] eq '*' || existsInList($_[0], $field->baseName))?1:0
  1004. -}
  1005. -
  1006. -# checks for eval
  1007. -sub checkEval {
  1008. -   return if $Settings::lockdown;
  1009. -  
  1010. -   #if ($_[0] =~ /;/) {
  1011. -   #   my @eval = split(/\s*;\s*/, $_[0]);
  1012. -   #   foreach my $e (@eval) {return 1 if checkEval($e)}
  1013. -   #   return 0
  1014. -   #}
  1015. -   return eval $_[0];
  1016. -}
  1017. -
  1018. -
  1019. -# releases a locked automacro ##################
  1020. -sub releaseAM {
  1021. -   if ($_[0] eq 'all') {
  1022. -       foreach (keys %automacro) {
  1023. -           undef $automacro{$_}->{disabled}
  1024. -       }
  1025. -       return 1
  1026. -   }
  1027. -   if (defined $automacro{$_[0]}) {
  1028. -       undef $automacro{$_[0]}->{disabled};
  1029. -       return 1
  1030. -   }
  1031. -   return 0
  1032. -}
  1033. -
  1034. -# locks an automacro ##################
  1035. -sub lockAM {
  1036. -   if ($_[0] eq 'all') {
  1037. -       foreach (keys %automacro) {
  1038. -           $automacro{$_}->{disabled} = 1
  1039. -       }
  1040. -       return 1
  1041. -   }
  1042. -   if (defined $automacro{$_[0]}) {
  1043. -       $automacro{$_[0]}->{disabled} = 1;
  1044. -       return 1
  1045. -   }
  1046. -   return 0
  1047. -}
  1048. -
  1049. -# parses automacros and checks conditions #################
  1050. -sub automacroCheck {
  1051. -   my ($trigger, $args) = @_;
  1052. -   return unless ($conState == 5 && $char) || $trigger =~ /^(?:charSelectScreen|Network|packet)/;
  1053. -
  1054. -   # do not run an automacro if there's already a macro running and the running
  1055. -   # macro is non-interruptible
  1056. -   return if (defined $queue && !$queue->interruptible);
  1057. -
  1058. -   refreshGlobal();
  1059. -
  1060. -   CHKAM:
  1061. -   foreach my $am (sort {
  1062. -       ($automacro{$a}->{priority} or 0) <=> ($automacro{$b}->{priority} or 0)
  1063. -   } keys %automacro) {
  1064. -       next CHKAM if $automacro{$am}->{disabled};
  1065. -
  1066. -       if (defined $automacro{$am}->{call} && !defined $macro{$automacro{$am}->{call}}) {
  1067. -           error "automacro $am: macro ".$automacro{$am}->{call}." not found.\n";
  1068. -           $automacro{$am}->{disabled} = 1; return
  1069. -       }
  1070. -
  1071. -       if (defined $automacro{$am}->{timeout}) {
  1072. -           $automacro{$am}->{time} = 0 unless $automacro{$am}->{time};
  1073. -           my %tmptimer = (timeout => $automacro{$am}->{timeout}, time => $automacro{$am}->{time});
  1074. -           next CHKAM unless timeOut(\%tmptimer)
  1075. -       }
  1076. -
  1077. -       if (defined $automacro{$am}->{hook}) {
  1078. -           next CHKAM unless $trigger eq $automacro{$am}->{hook};
  1079. -           # save arguments
  1080. -           my $s = 0;
  1081. -           foreach my $save (@{$automacro{$am}->{save}}) {
  1082. -               if (defined $args->{$save}) {
  1083. -                   if (ref($args->{$save}) eq 'SCALAR') {
  1084. -                       $varStack{".hooksave$s"} = ${$args->{$save}}
  1085. -                   } else {
  1086. -                       if (!$::config{macro_nowarn} && ref($args->{$save}) ne '') {
  1087. -                           warning "[macro] \$.hooksave$s is of type ".ref($args->{$save}).". Take care!\n"
  1088. -                       }
  1089. -                       $varStack{".hooksave$s"} = $args->{$save}
  1090. -                   }
  1091. -               } else {
  1092. -                   error "[macro] \$args->{$save} does not exist\n"
  1093. -               }
  1094. -               $s++
  1095. -           }
  1096. -       } elsif (defined $automacro{$am}->{console}) {
  1097. -           if ($trigger eq 'log') {
  1098. -               next CHKAM unless checkConsole($automacro{$am}->{console}, $args)
  1099. -           } else {next CHKAM}
  1100. -       } elsif (defined $automacro{$am}->{spell}) {
  1101. -           if ($trigger =~ /^(?:is_casting|packet_skilluse)$/) {
  1102. -           next CHKAM unless checkCast($automacro{$am}->{spell}, $args)
  1103. -           } else {next CHKAM}
  1104. -       } elsif (defined $automacro{$am}->{pm}) {
  1105. -           if ($trigger eq 'packet_privMsg') {
  1106. -           next CHKAM unless checkMsg(".lastpm", $automacro{$am}->{pm}, $args)
  1107. -           } else {next CHKAM}
  1108. -       } elsif (defined $automacro{$am}->{pubm}) {
  1109. -           if ($trigger eq 'packet_pubMsg') {
  1110. -           next CHKAM unless checkMsg(".lastpub", $automacro{$am}->{pubm}, $args)
  1111. -           } else {next CHKAM}
  1112. -       } elsif (defined $automacro{$am}->{system}) {
  1113. -           if ($trigger eq 'packet_sysMsg') {
  1114. -           next CHKAM unless checkMsg(".lastsys", $automacro{$am}->{system}, $args)
  1115. -           } else {next CHKAM}
  1116. -       } elsif (defined $automacro{$am}->{party}) {
  1117. -           if ($trigger eq 'packet_partyMsg') {
  1118. -           next CHKAM unless checkMsg(".lastparty", $automacro{$am}->{party}, $args)
  1119. -           } else {next CHKAM}
  1120. -       } elsif (defined $automacro{$am}->{guild}) {
  1121. -           if ($trigger eq 'packet_guildMsg') {
  1122. -           next CHKAM unless checkMsg(".lastguild", $automacro{$am}->{guild}, $args)
  1123. -           } else {next CHKAM}
  1124. -       } elsif (defined $automacro{$am}->{mapchange}) {
  1125. -           if ($trigger eq 'packet_mapChange') {
  1126. -           next CHKAM unless checkMapChange($automacro{$am}->{mapchange})
  1127. -           } else {next CHKAM}
  1128. -       } elsif (defined $automacro{$am}->{playerguild}) {
  1129. -           if (($trigger eq 'player') || ($trigger eq 'charNameUpdate')) {
  1130. -           next CHKAM unless checkPersonGuild($automacro{$am}->{playerguild},$trigger,$args)
  1131. -           } else {next CHKAM}
  1132. -       } elsif (defined $automacro{$am}->{areaSpell}) {
  1133. -           if ($trigger eq 'packet_areaSpell') {
  1134. -           next CHKAM unless checkSpellsID($automacro{$am}->{areaSpell}, $args)
  1135. -           } else {next CHKAM}
  1136. -       }
  1137. -
  1138. -       next CHKAM if (defined $automacro{$am}->{map}    && $automacro{$am}->{map} ne $field->baseName);
  1139. -       next CHKAM if (defined $automacro{$am}->{class}  && !checkClass($automacro{$am}->{class}));
  1140. -       next CHKAM if (defined $automacro{$am}->{eval} && !checkEval($automacro{$am}->{eval}));
  1141. -       next CHKAM if (defined $automacro{$am}->{whenGround} && !checkGround($automacro{$am}->{whenGround}));
  1142. -       next CHKAM if (defined $automacro{$am}->{notMonster} && !checkMonster($automacro{$am}->{notMonster}, 1));
  1143. -
  1144. -       foreach my $i (@{$automacro{$am}->{monster}})    {next CHKAM unless checkMonster($i)}
  1145. -       foreach my $i (@{$automacro{$am}->{aggressives}}){next CHKAM unless checkAggressives($i)}
  1146. -       foreach my $i (@{$automacro{$am}->{location}})   {next CHKAM unless checkLoc($i)}
  1147. -       foreach my $i (@{$automacro{$am}->{localtime}})  {next CHKAM unless checkLocalTime($i, "")}
  1148. -       foreach my $i (@{$automacro{$am}->{var}})        {next CHKAM unless checkVar($i, "")}
  1149. -       foreach my $i (@{$automacro{$am}->{varvar}})     {next CHKAM unless checkVar($i, "varvar")}
  1150. -       foreach my $i (@{$automacro{$am}->{base}})       {next CHKAM unless checkLevel($i, "lv")}
  1151. -       foreach my $i (@{$automacro{$am}->{job}})        {next CHKAM unless checkLevel($i, "lv_job")}
  1152. -       foreach my $i (@{$automacro{$am}->{hp}})         {next CHKAM unless checkPercent($i, "hp")}
  1153. -       foreach my $i (@{$automacro{$am}->{sp}})         {next CHKAM unless checkPercent($i, "sp")}
  1154. -       foreach my $i (@{$automacro{$am}->{spirit}})     {next CHKAM unless checkCond($char->{spirits} || 0, $i)}
  1155. -       foreach my $i (@{$automacro{$am}->{weight}})     {next CHKAM unless checkPercent($i, "weight")}
  1156. -       foreach my $i (@{$automacro{$am}->{cartweight}}) {next CHKAM unless checkPercent($i, "cweight")}
  1157. -       foreach my $i (@{$automacro{$am}->{soldout}})    {next CHKAM unless checkCond(getSoldOut(), $i)}
  1158. -       foreach my $i (@{$automacro{$am}->{zeny}})       {next CHKAM unless checkCond($char->{zeny}, $i)}
  1159. -       foreach my $i (@{$automacro{$am}->{cash}})       {next CHKAM unless checkCond($cashShop{points}->{cash}?$cashShop{points}->{cash}:0, $i)}
  1160. -       foreach my $i (@{$automacro{$am}->{player}})     {next CHKAM unless checkPerson($i)}
  1161. -       foreach my $i (@{$automacro{$am}->{equipped}})   {next CHKAM unless checkEquip($i)}
  1162. -       foreach my $i (@{$automacro{$am}->{status}})     {next CHKAM unless checkStatus($i)}
  1163. -       foreach my $i (@{$automacro{$am}->{inventory}})  {next CHKAM unless checkItem("inv", $i)}
  1164. -       foreach my $i (@{$automacro{$am}->{storage}})    {next CHKAM unless checkItem("stor", $i)}
  1165. -       foreach my $i (@{$automacro{$am}->{shop}})       {next CHKAM unless checkItem("shop", $i)}
  1166. -       foreach my $i (@{$automacro{$am}->{cart}})       {next CHKAM unless checkItem("cart", $i)}
  1167. -
  1168. -       message "[macro] automacro $am triggered.\n", "macro";
  1169. -
  1170. -       unless (defined $automacro{$am}->{call} || $::config{macro_nowarn}) {
  1171. -           warning "[macro] automacro $am: call not defined.\n", "macro"
  1172. -       }
  1173. -
  1174. -       $automacro{$am}->{time} = time  if $automacro{$am}->{timeout};
  1175. -       $automacro{$am}->{disabled} = 1 if $automacro{$am}->{'run-once'};
  1176. -
  1177. -       foreach my $i (@{$automacro{$am}->{set}}) {
  1178. -           my ($var, $val) = $i =~ /^(.*?)\s+(.*)/;
  1179. -           $varStack{$var} = $val
  1180. -       }
  1181. -
  1182. -       if (defined $automacro{$am}->{call}) {
  1183. -           undef $queue if defined $queue;
  1184. -           $queue = new Macro::Script($automacro{$am}->{call});
  1185. -           if (defined $queue) {
  1186. -               $queue->overrideAI(1) if $automacro{$am}->{overrideAI};
  1187. -               $queue->interruptible(0) if $automacro{$am}->{exclusive};
  1188. -               $queue->orphan($automacro{$am}->{orphan}) if defined $automacro{$am}->{orphan};
  1189. -               $queue->timeout($automacro{$am}->{delay}) if $automacro{$am}->{delay};
  1190. -               $queue->setMacro_delay($automacro{$am}->{macro_delay}) if $automacro{$am}->{macro_delay};
  1191. -               $varStack{".caller"} = $am;
  1192. -               $onHold = 0;
  1193. -               callMacro
  1194. -           } else {
  1195. -               error "unable to create macro queue.\n"
  1196. -           }
  1197. -       }
  1198. -
  1199. -       return # don't execute multiple macros at once
  1200. -   }
  1201. -}
  1202. -
  1203. -1;
  1204. +1;
  1205. \ No newline at end of file
  1206. Index: Macro/Condition/base.pm
  1207. ===================================================================
  1208. --- Macro/Condition/base.pm (revision 0)
  1209. +++ Macro/Condition/base.pm (working copy)
  1210. @@ -0,0 +1,74 @@
  1211. +package Macro::Condition::Base;
  1212. +
  1213. +use strict;
  1214. +use Plugins;
  1215. +use Settings;
  1216. +use Globals;
  1217. +use Macro::Data;
  1218. +use Macro::Utilities qw(cmpr);
  1219. +
  1220. +sub new {
  1221. +   my ($class, $text) = @_;
  1222. +   my $self = {
  1223. +       text => $text,
  1224. +       listIndex => -1,
  1225. +       isSingle => 0,
  1226. +       isTrue => 0,
  1227. +       hooks => ['level_changed'],
  1228. +       variables => []
  1229. +   };
  1230. +   bless $self, $class;
  1231. +   return 0 unless ($self->isSintaxCorrect());
  1232. +   return $self;
  1233. +}
  1234. +
  1235. +sub check {
  1236. +   my ($self, $event, $args) = @_;
  1237. +   if ($event ne "var") {
  1238. +       if ($self->{varType}) {
  1239. +           if ($macroPlugin->isVarDefined($self->{lvl})) {
  1240. +               $self->{isTrue} = cmpr($char->{lv}, $self->{cond}, $macroPlugin->getVar($self->{lvl}));
  1241. +           } else {
  1242. +               $self->{isTrue} = 0;
  1243. +           }
  1244. +       } else {
  1245. +           $self->{isTrue} = cmpr($char->{lv}, $self->{cond}, $self->{lvl});
  1246. +       }
  1247. +   } else {
  1248. +       $self->{isTrue} = cmpr($char->{lv}, $self->{cond}, $macroPlugin->getVar($self->{lvl}));
  1249. +   }
  1250. +   return 1 if ($self->{isTrue});
  1251. +   return 0;
  1252. +}
  1253. +
  1254. +sub isTrue {
  1255. +   my ($self) = @_;
  1256. +   return $self->{isTrue};
  1257. +}
  1258. +
  1259. +sub isSintaxCorrect {
  1260. +   my ($self) = @_;
  1261. +   if ($self->{text} =~ /([<>=!]+)\s+(\$[a-zA-Z][a-zA-Z\d]*|\d+|\d+\s*\.{2}\s*\d+)\s*$/) {
  1262. +       $self->{cond} = $1;
  1263. +       my $lvl = $2;
  1264. +       if ($lvl =~ /^\s*\$/) {
  1265. +           my ($var) = $lvl =~ /^\$([a-zA-Z][a-zA-Z\d]*)\s*$/;
  1266. +           return 0 unless defined $var;
  1267. +           $self->{lvl} = $var;
  1268. +           push (@{$self->{variables}}, $var);
  1269. +           $self->{varType} = 1;
  1270. +       } else {
  1271. +           $self->{lvl} = $lvl;
  1272. +           $self->{varType} = 0;
  1273. +       }
  1274. +       return 1;
  1275. +   }
  1276. +   return 0;
  1277. +}
  1278. +
  1279. +sub isSingleCondition {
  1280. +   my ($self) = @_;
  1281. +   return $self->{isSingle};
  1282. +}
  1283. +
  1284. +1;
  1285. \ No newline at end of file
  1286. Index: Macro/Condition/base.pm
  1287. ===================================================================
  1288. --- Macro/Condition/base.pm (revision 0)
  1289. +++ Macro/Condition/base.pm (working copy)
  1290. @@ -0,0 +1,74 @@
  1291. +package Macro::Condition::Base;
  1292. +
  1293. +use strict;
  1294. +use Plugins;
  1295. +use Settings;
  1296. +use Globals;
  1297. +use Macro::Data;
  1298. +use Macro::Utilities qw(cmpr);
  1299. +
  1300. +sub new {
  1301. +   my ($class, $text) = @_;
  1302. +   my $self = {
  1303. +       text => $text,
  1304. +       listIndex => -1,
  1305. +       isSingle => 0,
  1306. +       isTrue => 0,
  1307. +       hooks => ['level_changed'],
  1308. +       variables => []
  1309. +   };
  1310. +   bless $self, $class;
  1311. +   return 0 unless ($self->isSintaxCorrect());
  1312. +   return $self;
  1313. +}
  1314. +
  1315. +sub check {
  1316. +   my ($self, $event, $args) = @_;
  1317. +   if ($event ne "var") {
  1318. +       if ($self->{varType}) {
  1319. +           if ($macroPlugin->isVarDefined($self->{lvl})) {
  1320. +               $self->{isTrue} = cmpr($char->{lv}, $self->{cond}, $macroPlugin->getVar($self->{lvl}));
  1321. +           } else {
  1322. +               $self->{isTrue} = 0;
  1323. +           }
  1324. +       } else {
  1325. +           $self->{isTrue} = cmpr($char->{lv}, $self->{cond}, $self->{lvl});
  1326. +       }
  1327. +   } else {
  1328. +       $self->{isTrue} = cmpr($char->{lv}, $self->{cond}, $macroPlugin->getVar($self->{lvl}));
  1329. +   }
  1330. +   return 1 if ($self->{isTrue});
  1331. +   return 0;
  1332. +}
  1333. +
  1334. +sub isTrue {
  1335. +   my ($self) = @_;
  1336. +   return $self->{isTrue};
  1337. +}
  1338. +
  1339. +sub isSintaxCorrect {
  1340. +   my ($self) = @_;
  1341. +   if ($self->{text} =~ /([<>=!]+)\s+(\$[a-zA-Z][a-zA-Z\d]*|\d+|\d+\s*\.{2}\s*\d+)\s*$/) {
  1342. +       $self->{cond} = $1;
  1343. +       my $lvl = $2;
  1344. +       if ($lvl =~ /^\s*\$/) {
  1345. +           my ($var) = $lvl =~ /^\$([a-zA-Z][a-zA-Z\d]*)\s*$/;
  1346. +           return 0 unless defined $var;
  1347. +           $self->{lvl} = $var;
  1348. +           push (@{$self->{variables}}, $var);
  1349. +           $self->{varType} = 1;
  1350. +       } else {
  1351. +           $self->{lvl} = $lvl;
  1352. +           $self->{varType} = 0;
  1353. +       }
  1354. +       return 1;
  1355. +   }
  1356. +   return 0;
  1357. +}
  1358. +
  1359. +sub isSingleCondition {
  1360. +   my ($self) = @_;
  1361. +   return $self->{isSingle};
  1362. +}
  1363. +
  1364. +1;
  1365. \ No newline at end of file
  1366. Index: Macro/Data.pm
  1367. ===================================================================
  1368. --- Macro/Data.pm   (revision 8992)
  1369. +++ Macro/Data.pm   (working copy)
  1370. @@ -6,73 +6,24 @@
  1371.  require Exporter;
  1372.  our ($rev) = q$Revision: 6753 $ =~ /(\d+)/;
  1373.  our @ISA = qw(Exporter);
  1374. -our @EXPORT = qw(@perl_name %macro %automacro %varStack $queue $onHold %amSingle %amMulti $macroKeywords);
  1375. +our @EXPORT = qw($macroPlugin @perl_name %parameters $macroKeywords);
  1376.  
  1377. +our $macroPlugin;
  1378.  our @perl_name;
  1379. -our %macro;
  1380. -our %automacro;
  1381. -our %varStack;
  1382. -our $queue;
  1383. -our $onHold;
  1384. -our $inBlock;
  1385.  
  1386. -our %amSingle = (
  1387. -   'map' => 1,          # map check
  1388. -   'mapchange' => 1,    # map change check
  1389. -   'class' => 1,        # job class check
  1390. +our %parameters = (
  1391.     'timeout' => 1,      # setting: re-check timeout
  1392.     'delay' => 1,        # option: delay before the macro starts
  1393.     'run-once' => 1,     # option: run automacro only once
  1394.     'disabled' => 1,     # option: automacro disabled
  1395.     'call' => 1,         # setting: macro to be called
  1396. -   'spell' => 1,        # check: cast sensor
  1397. -   'notMonster' => 1,   # check: disallow monsters other than ~
  1398. -   'pm' => 1,           # check: private message
  1399. -   'pubm' => 1,         # check: public chat
  1400. -   'system' => 1,       # check: system chat
  1401. -   'guild' => 1,        # check: guild chat
  1402. -   'party' => 1,        # check: party chat
  1403. -   'console' => 1,      # check: console message
  1404.     'overrideAI' => 1,   # option: override AI
  1405.     'orphan' => 1,       # option: orphan handling
  1406.     'macro_delay' => 1,  # option: default macro delay
  1407. -   'hook' => 1,         # check: openkore hook
  1408.     'priority' => 1,     # option: automacro priority
  1409.     'exclusive' => 1,    # option: is macro interruptible
  1410. -   'playerguild' => 1,  # check: player guilds
  1411. -   'eval' => 1,         # check : eval
  1412. -   'whenGround' => 1,   # check : when ground statuses
  1413. -   'areaSpell' => 1     # check : area spell
  1414.  );
  1415.  
  1416. -our %amMulti = (
  1417. -   'set' => 1,          # set: variable
  1418. -   'save' => 1,         # setting: save hook arguments
  1419. -   'monster' => 1,      # check: monster on screen
  1420. -   'aggressives' => 1,  # check: aggressives
  1421. -   'location' => 1,     # check: player's location
  1422. -   'var' => 1,          # check: variable / value
  1423. -   'varvar' => 1,       # check: nested variable / value
  1424. -   'base' => 1,         # check: base level
  1425. -   'job' => 1,          # check: job level
  1426. -   'hp' => 1,           # check: player's hp
  1427. -   'sp' => 1,           # check: player's sp
  1428. -   'spirit' => 1,       # check: spirit spheres
  1429. -   'weight' => 1,       # check: player's weight
  1430. -   'cartweight' => 1,   # check: cart weight
  1431. -   'soldout' => 1,      # check: sold out shop slots
  1432. -   'zeny' => 1,         # check: player's zeny
  1433. -   'cash' => 1,         # check: player's cash
  1434. -   'player' => 1,       # check: player name near
  1435. -   'equipped' => 1,     # check: equipment
  1436. -   'status' => 1,       # check: player's status
  1437. -   'inventory' => 1,    # check: item amount in inventory
  1438. -   'storage' => 1,      # check: item amount in storage
  1439. -   'shop' => 1,         # check: item amount in shop
  1440. -   'cart' => 1,         # check: item amount in cart
  1441. -   'localtime' => 1     # check: localtime
  1442. -);
  1443. -
  1444.  our $macroKeywords =
  1445.     "npc"          . "|" .
  1446.     "store"        . "|" .
  1447. Index: Macro/FileParser.pm
  1448. ===================================================================
  1449. --- Macro/FileParser.pm (revision 0)
  1450. +++ Macro/FileParser.pm (working copy)
  1451. @@ -0,0 +1,382 @@
  1452. +# $Id: Parser.pm r6759 2009-07-05 04:00:00Z ezza $
  1453. +package Macro::FileParser;
  1454. +
  1455. +use strict;
  1456. +use encoding 'utf8';
  1457. +
  1458. +require Exporter;
  1459. +our @ISA = qw(Exporter);
  1460. +our @EXPORT = qw(parseMacroFile isNewCommandBlock);
  1461. +our @EKSPORT_OK = qw(isNewCommandBlock);
  1462. +
  1463. +use Globals;
  1464. +use Utils;
  1465. +use Utils::Exceptions;
  1466. +use List::Util qw(max min sum);
  1467. +use Log qw(message warning error);
  1468. +use Text::Balanced qw/extract_bracketed/;
  1469. +use Macro::Data;
  1470. +use Macro::Plugin;
  1471. +use Macro::Lists;
  1472. +use Macro::Lists::Automacro;
  1473. +use Macro::Lists::Condition;
  1474. +use Macro::Lists::Macro;
  1475. +our ($rev) = q$Revision: 6759 $ =~ /(\d+)/;
  1476. +
  1477. +# adapted config file parser
  1478. +my $tempmacro = 0;
  1479. +my %macro;
  1480. +my %automacro;
  1481. +
  1482. +sub parseMacroFile {
  1483. +   my ($file, $recursive) = @_;
  1484. +  
  1485. +   unless ($recursive) {
  1486. +       undef %macro;
  1487. +       undef %automacro;
  1488. +       undef @perl_name
  1489. +   }
  1490. +
  1491. +   my %block;
  1492. +   my $inBlock = 0;
  1493. +   my $macroCountOpenBlock = 0;
  1494. +   my ($macro_subs, @perl_lines);
  1495. +   open my $fp, "<:utf8", $file or return 0;
  1496. +   while (<$fp>) {
  1497. +       $. == 1 &&
  1498. +       s/^\x{FEFF}//;          # utf bom
  1499. +       s/(.*)[\s\t]+#.*$/$1/;  # remove last comments
  1500. +       s/^\s*#.*$//;           # remove comments
  1501. +       s/^\s*//;               # remove leading whitespaces
  1502. +       s/\s*[\r\n]?$//g;       # remove trailing whitespaces and eol
  1503. +       s/  +/ /g;              # trim down spaces - very cool for user's string data?
  1504. +       next unless ($_);
  1505. +
  1506. +       if (!%block && /{$/) {
  1507. +           my ($key, $value) = $_ =~ /^(.*?)\s+(.*?)\s*{$/;
  1508. +           if ($key eq 'macro') {
  1509. +               %block = (name => $value, type => "macro");
  1510. +               $macro{$value} = [];
  1511. +           } elsif ($key eq 'automacro') {
  1512. +               %block = (name => $value, type => "automacro");
  1513. +           } elsif ($key eq 'sub') {
  1514. +               %block = (name => $value, type => "sub");
  1515. +           } else {
  1516. +               %block = (type => "bogus");
  1517. +               warning "$file: ignoring line '$_' in line $. (munch, munch, strange block)\n";
  1518. +           }
  1519. +           next;
  1520. +
  1521. +
  1522. +
  1523. +
  1524. +       } elsif (%block && $block{type} eq "bogus") {
  1525. +           if ($_ eq "}") {undef %block}
  1526. +           next;
  1527. +
  1528. +
  1529. +
  1530. +
  1531. +       } elsif (%block && $block{type} eq "macro") {
  1532. +           if ($_ eq "}") {
  1533. +               if ($macroCountOpenBlock) {
  1534. +                   push(@{$macro{$block{name}}}, '}');
  1535. +                   $macroCountOpenBlock--;
  1536. +               } else {
  1537. +                   undef %block;
  1538. +               }
  1539. +           } else {
  1540. +               if (isNewCommandBlock($_)) {
  1541. +                   $macroCountOpenBlock++
  1542. +               } elsif (!$macroCountOpenBlock && isNewWrongCommandBlock($_)) {
  1543. +                   warning "$file: ignoring '$_' in line $. (munch, munch, not found the open block command)\n";
  1544. +                   next;
  1545. +               }
  1546. +               push(@{$macro{$block{name}}}, $_);
  1547. +           }
  1548. +          
  1549. +           next;
  1550. +
  1551. +
  1552. +
  1553. +          
  1554. +       } elsif (%block && $block{type} eq "automacro") {
  1555. +           if ($_ eq "}") {
  1556. +               if ($block{loadmacro}) {
  1557. +                   if ($macroCountOpenBlock) {
  1558. +                       push(@{$macro{$block{loadmacro_name}}}, '}');
  1559. +                      
  1560. +                       if ($macroCountOpenBlock) {
  1561. +                           $macroCountOpenBlock--;
  1562. +                       }
  1563. +                   } else {
  1564. +                       undef $block{loadmacro}
  1565. +                   }
  1566. +               } else {
  1567. +                   undef %block
  1568. +               }
  1569. +           } elsif ($_ eq "call {") {
  1570. +               $block{loadmacro} = 1;
  1571. +               $block{loadmacro_name} = "tempMacro".$tempmacro++;
  1572. +               push(@{$automacro{$block{name}}{parameters}}, {key => 'call', value => $block{loadmacro_name}});
  1573. +               $macro{$block{loadmacro_name}} = []
  1574. +           } elsif ($block{loadmacro}) {
  1575. +               if (isNewCommandBlock($_)) {
  1576. +                   $macroCountOpenBlock++
  1577. +               } elsif (!$macroCountOpenBlock && isNewWrongCommandBlock($_)) {
  1578. +                   warning "$file: ignoring '$_' in line $. (munch, munch, not found the open block command)\n";
  1579. +                   next
  1580. +               }
  1581. +
  1582. +               push(@{$macro{$block{loadmacro_name}}}, $_);
  1583. +           } else {
  1584. +               my ($key, $value) = $_ =~ /^(.*?)\s+(.*)/;
  1585. +               if (!defined $key || !defined $value) {
  1586. +                   warning "$file: ignoring '$_' in line $. (munch, munch, not a pair)\n";
  1587. +                   next;
  1588. +               }
  1589. +               if (exists $parameters{$key}) {
  1590. +                   push(@{$automacro{$block{name}}{parameters}}, {key => $key, value => $value});
  1591. +               } else {
  1592. +                   push(@{$automacro{$block{name}}{conditions}}, {key => $key, value => $value});
  1593. +               }
  1594. +           }
  1595. +          
  1596. +           next;
  1597. +
  1598. +
  1599. +
  1600. +
  1601. +       } elsif (%block && $block{type} eq "sub") {
  1602. +           if ($_ eq "}") {
  1603. +               if ($inBlock > 0) {
  1604. +                   push(@perl_lines, $_);
  1605. +                   $inBlock--;
  1606. +                   next
  1607. +               }
  1608. +               $macro_subs = join('', @perl_lines);
  1609. +               sub_execute($block{name}, $macro_subs);
  1610. +               push(@perl_name, $block{name}) unless existsInList(join(',', @perl_name), $block{name});
  1611. +               undef %block; undef @perl_lines; undef $macro_subs;
  1612. +               $inBlock = 0
  1613. +           }
  1614. +           elsif ($_ =~ /^}.*?{$/ && $inBlock > 0) {push(@perl_lines, $_)}
  1615. +           elsif ($_ =~ /{$/) {$inBlock++; push(@perl_lines, $_)}
  1616. +           else {push(@perl_lines, $_)}
  1617. +           next;
  1618. +
  1619. +
  1620. +
  1621. +
  1622. +       }
  1623. +
  1624. +       my ($key, $value) = $_ =~ /(?:^(.*?)\s|})+(.*)/;
  1625. +       unless (defined $key) {
  1626. +           warning "$file: ignoring '$_' in line $. (munch, munch, strange food)\n";
  1627. +           next
  1628. +       }
  1629. +
  1630. +       if ($key eq "!include") {
  1631. +           my $f = $value;
  1632. +           if (!File::Spec->file_name_is_absolute($value) && $value !~ /^\//) {
  1633. +               if ($file =~ /[\/\\]/) {
  1634. +                   $f = $file;
  1635. +                   $f =~ s/(.*)[\/\\].*/$1/;
  1636. +                   $f = File::Spec->catfile($f, $value)
  1637. +               } else {
  1638. +                   $f = $value
  1639. +               }
  1640. +           }
  1641. +           if (-f $f) {
  1642. +               my $ret = parseMacroFile($f, 1);
  1643. +               return $ret unless $ret
  1644. +           } else {
  1645. +               error "$file: Include file not found: $f\n";
  1646. +               return 0
  1647. +           }
  1648. +       }
  1649. +   }
  1650. +  
  1651. +   &createMacroObjects(\%macro);
  1652. +   &createAutomacroObjects(\%automacro);
  1653. +  
  1654. +   close $fp;
  1655. +   return 0 if %block;
  1656. +   return 1
  1657. +}
  1658. +
  1659. +sub createMacroObjects {
  1660. +   my ($macro) = @_;
  1661. +   my $currentMacro;
  1662. +   while (my ($name,$lines) = each %{$macro}) {
  1663. +       $currentMacro = new Macro::Macro($name, $lines);
  1664. +       $macroPlugin->{macro}->add($currentMacro);
  1665. +   } continue {
  1666. +       undef $currentMacro;
  1667. +   }
  1668. +}
  1669. +
  1670. +sub createAutomacroObjects {
  1671. +   my ($automacro) = @_;
  1672. +   my $currentAutomacro;
  1673. +   my %modulesLoaded;
  1674. +   my $autoModule;
  1675. +   my %currentConditions;
  1676. +   my %currentParameters;
  1677. +   my $conditionObject;
  1678. +   AUTOMACRO: while (my ($name,$value) = each %{$automacro}) {
  1679. +      
  1680. +       ####################################
  1681. +       #####No Conditions Check
  1682. +       ####################################
  1683. +       if (!exists $value->{'conditions'} || !@{$value->{'conditions'}}) {
  1684. +           print AUTO "Ignoring automacro '$name' (munch, munch, no condition set)\n";
  1685. +           next AUTOMACRO;
  1686. +       }
  1687. +  
  1688. +       ####################################
  1689. +       #####No Parameters Check
  1690. +       ####################################
  1691. +       if (!exists $value->{'parameters'} || !@{$value->{'parameters'}}) {
  1692. +           print AUTO "Ignoring automacro '$name' (munch, munch, no parameter set)\n";
  1693. +           next AUTOMACRO;
  1694. +       }
  1695. +      
  1696. +       PARAMETER: foreach my $parameter (@{$value->{'parameters'}}) {
  1697. +      
  1698. +           ###Check Duplicate Parameter
  1699. +           if (exists $currentParameters{$parameter->{'key'}}) {
  1700. +               warning "Ignoring automacro '$name' (munch, munch, parameter ".$parameter->{'key'}." duplicate)\n";
  1701. +               next AUTOMACRO;
  1702. +           }
  1703. +           ###Parameter: call
  1704. +           if ($parameter->{'key'} eq "call" && !$macroPlugin->{macro}->getByName($parameter->{'value'})) {
  1705. +               warning "Ignoring automacro '$name' (munch, munch, call not a valid macro name)\n";
  1706. +               next AUTOMACRO;
  1707. +          
  1708. +           ###Parameter: delay
  1709. +           } elsif ($parameter->{'key'} eq "delay" && $parameter->{'value'} !~ /\d+/) {
  1710. +               print AUTO "Ignoring automacro '$name' (munch, munch, delay parameter set wrong)\n";
  1711. +               next AUTOMACRO;
  1712. +          
  1713. +           ###Parameter: run-once
  1714. +           } elsif ($parameter->{'key'} eq "run-once" && $parameter->{'value'} !~ /[01]/) {
  1715. +               print AUTO "Ignoring automacro '$name' (munch, munch, run-once parameter set wrong)\n";
  1716. +               next AUTOMACRO;
  1717. +          
  1718. +           ###Parameter: disabled
  1719. +           } elsif ($parameter->{'key'} eq "disabled" && $parameter->{'value'} !~ /[01]/) {
  1720. +               print AUTO "Ignoring automacro '$name' (munch, munch, disabled parameter set wrong)\n";
  1721. +               next AUTOMACRO;
  1722. +          
  1723. +           ###Parameter: overrideAI
  1724. +           } elsif ($parameter->{'key'} eq "overrideAI" && $parameter->{'value'} !~ /[01]/) {
  1725. +               print AUTO "Ignoring automacro '$name' (munch, munch, overrideAI parameter set wrong)\n";
  1726. +               next AUTOMACRO;
  1727. +          
  1728. +           ###Parameter: exclusive
  1729. +           } elsif ($parameter->{'key'} eq "exclusive" && $parameter->{'value'} !~ /[01]/) {
  1730. +               print AUTO "Ignoring automacro '$name' (munch, munch, exclusive parameter set wrong)\n";
  1731. +               next AUTOMACRO;
  1732. +          
  1733. +           ###Parameter: priority
  1734. +           } elsif ($parameter->{'key'} eq "priority" && $parameter->{'value'} !~ /\d+/) {
  1735. +               print AUTO "Ignoring automacro '$name' (munch, munch, priority parameter set wrong)\n";
  1736. +               next AUTOMACRO;
  1737. +          
  1738. +           ###Parameter: macro_delay
  1739. +           } elsif ($parameter->{'key'} eq "macro_delay" && $parameter->{'value'} !~ /(\d+|\d+\.\d+)/) {
  1740. +               print AUTO "Ignoring automacro '$name' (munch, munch, macro_delay parameter set wrong)\n";
  1741. +               next AUTOMACRO;
  1742. +          
  1743. +           ###Parameter: orphan
  1744. +           } elsif ($parameter->{'key'} eq "orphan" && $parameter->{'value'} !~ /(terminate|reregister|reregister_safe)/) {
  1745. +               print AUTO "Ignoring automacro '$name' (munch, munch, orphan parameter set wrong)\n";
  1746. +               next AUTOMACRO;
  1747. +           } else {
  1748. +               $currentParameters{$parameter->{'key'}} = $parameter->{'value'};
  1749. +           }
  1750. +       }
  1751. +      
  1752. +       ###Recheck Parameter call
  1753. +       if (!exists $currentParameters{'call'}) {
  1754. +           warning "Ignoring automacro '$name' (munch, munch, no macro call set)\n";
  1755. +           next AUTOMACRO;
  1756. +       }
  1757. +      
  1758. +       ####################################
  1759. +       #####Conditions Check
  1760. +       ####################################
  1761. +       CONDITION: foreach my $condition (@{$value->{'conditions'}}) {
  1762. +           $autoModule = "Macro::Condition::".ucfirst($condition->{'key'});
  1763. +           if (!exists $modulesLoaded{$autoModule}) {
  1764. +               undef $@;
  1765. +               message "[Macro] Loading module $autoModule\n";
  1766. +               eval "use $autoModule";
  1767. +               if ($@ =~ /^Can't locate /s) {
  1768. +                   FileNotFoundException->throw("Cannot load automacro module ".$autoModule." for condition ".$condition->{'key'}.". Ignoring automacro ".$name.".");
  1769. +                   next AUTOMACRO;
  1770. +               } elsif ($@) {
  1771. +                   ModuleLoadException->throw("An error occured while loading the automacro condition ".$condition->{'key'}.":".$@.". Ignoring automacro ".$name.".");
  1772. +                   next AUTOMACRO;
  1773. +               }
  1774. +               $modulesLoaded{$autoModule} = 1;
  1775. +           }
  1776. +           $conditionObject = $autoModule->new($condition->{'value'});
  1777. +           next AUTOMACRO if (!$conditionObject);
  1778. +           next AUTOMACRO if (exists $currentConditions{$autoModule} && $conditionObject->isSingleCondition());
  1779. +           push(@{$currentConditions{$autoModule}}, $condition->{'value'});
  1780. +       } continue {
  1781. +           undef $conditionObject;
  1782. +           undef $autoModule;
  1783. +       }
  1784. +      
  1785. +       ####################################
  1786. +       #####Automacro Object Creation
  1787. +       ####################################
  1788. +       $currentAutomacro = new Macro::Automacro($name, \%currentConditions, \%currentParameters);
  1789. +       $macroPlugin->{automacro}->add($currentAutomacro);
  1790. +   } continue {
  1791. +       undef $conditionObject;
  1792. +       undef $autoModule;
  1793. +       undef $currentAutomacro;
  1794. +       undef %currentConditions;
  1795. +       undef %currentParameters;
  1796. +   }
  1797. +}
  1798. +
  1799. +sub sub_execute {
  1800. +   return if $Settings::lockdown;
  1801. +  
  1802. +   my ($name, $arg) = @_;
  1803. +   my $run = "sub ".$name." {".$arg."}";
  1804. +   eval($run);         # cycle the macro sub between macros only
  1805. +   $run = "eval ".$run;
  1806. +   Commands::run($run);        # exporting sub to the &main::sub, becarefull on your sub name
  1807. +                   # dont name your new sub equal to any &main::sub, you should take
  1808. +                   # the risk yourself.
  1809. +   message "[macro] registering sub $name ...\n", "menu";
  1810. +}
  1811. +
  1812. +# check if on the line there commands that open new command blocks
  1813. +sub isNewCommandBlock {
  1814. +   my ($line) = @_;
  1815. +  
  1816. +   if ($line =~ /^if.*{$/ || $line =~ /^case.*{$/ || $line =~ /^switch.*{$/ || $line =~ /^else.*{$/) {
  1817. +       return 1;
  1818. +   } else {
  1819. +       return 0;
  1820. +   }
  1821. +}
  1822. +
  1823. +sub isNewWrongCommandBlock {
  1824. +   my ($line) = @_;
  1825. +  
  1826. +   if ($_ =~ /^}\s*else\s*{$/ || $_ =~ /}\s*elsif.*{$/ || $_ =~ /^case.*{$/ || $_ =~ /^else*{$/) {
  1827. +       return 1;
  1828. +   } else {
  1829. +       return 0;
  1830. +   }
  1831. +}
  1832. +
  1833. +1;
  1834. \ No newline at end of file
  1835. Index: Macro/Lists/Automacro.pm
  1836. ===================================================================
  1837. --- Macro/Lists/Automacro.pm    (revision 0)
  1838. +++ Macro/Lists/Automacro.pm    (working copy)
  1839. @@ -0,0 +1,32 @@
  1840. +#########################################################################
  1841. +#  OpenKore - Player actor object
  1842. +#  Copyright (c) 2005 OpenKore Team
  1843. +#
  1844. +#  TEST BY HENRYBK
  1845. +#
  1846. +#########################################################################
  1847. +package Macro::Lists::Automacro;
  1848. +
  1849. +use strict;
  1850. +use Globals;
  1851. +use Macro::Lists;
  1852. +use base qw(Macro::Lists);
  1853. +
  1854. +sub new {
  1855. +   my ($class) = @_;
  1856. +   my $self = $class->SUPER::new('Automacro');
  1857. +   #$self->{hooks} = Plugins::addHooks (['packet/stat_info2',        sub { $self->{state} = RECV_STAT_INFO2; }]);
  1858. +   return $self;
  1859. +}
  1860. +
  1861. +sub getByMacroCalled {
  1862. +   my ($self, $macroName) = @_;
  1863. +   foreach my $automacro (@{$self->getItems()}) {
  1864. +       if ($automacro->{parameters}{call} eq $macroName) {
  1865. +           return $automacro;
  1866. +       }
  1867. +   }
  1868. +   return undef;
  1869. +}
  1870. +
  1871. +1;
  1872. \ No newline at end of file
  1873. Index: Macro/Lists/Condition.pm
  1874. ===================================================================
  1875. --- Macro/Lists/Condition.pm    (revision 0)
  1876. +++ Macro/Lists/Condition.pm    (working copy)
  1877. @@ -0,0 +1,32 @@
  1878. +package Macro::Lists::Condition;
  1879. +
  1880. +use strict;
  1881. +use Carp::Assert;
  1882. +use Utils::ObjectList;
  1883. +use base qw(ObjectList);
  1884. +
  1885. +sub new {
  1886. +   my ($class) = @_;
  1887. +   my $self = $class->SUPER::new();
  1888. +
  1889. +   return $self;
  1890. +}
  1891. +
  1892. +sub DESTROY {
  1893. +   my ($self) = @_;
  1894. +   Plugins::delHook($self->{hook}) if $self->{hook};
  1895. +   $self->clear();
  1896. +   $self->SUPER::DESTROY();
  1897. +}
  1898. +
  1899. +sub add {
  1900. +   my ($self, $member) = @_;
  1901. +
  1902. +   my $listIndex = $self->SUPER::add($member);
  1903. +   $member->{listIndex} = $listIndex;
  1904. +
  1905. +   return $listIndex;
  1906. +}
  1907. +
  1908. +
  1909. +1;
  1910. Index: Macro/Lists/Macro.pm
  1911. ===================================================================
  1912. --- Macro/Lists/Macro.pm    (revision 0)
  1913. +++ Macro/Lists/Macro.pm    (working copy)
  1914. @@ -0,0 +1,21 @@
  1915. +#########################################################################
  1916. +#  OpenKore - Player actor object
  1917. +#  Copyright (c) 2005 OpenKore Team
  1918. +#
  1919. +#  TEST BY HENRYBK
  1920. +#
  1921. +#########################################################################
  1922. +package Macro::Lists::Macro;
  1923. +
  1924. +use strict;
  1925. +use Globals;
  1926. +use Macro::Lists;
  1927. +use base qw(Macro::Lists);
  1928. +
  1929. +sub new {
  1930. +   my ($class) = @_;
  1931. +   my $self = $class->SUPER::new('Macro');
  1932. +   return $self;
  1933. +}
  1934. +
  1935. +1;
  1936. \ No newline at end of file
  1937. Index: Macro/Lists.pm
  1938. ===================================================================
  1939. --- Macro/Lists.pm  (revision 0)
  1940. +++ Macro/Lists.pm  (working copy)
  1941. @@ -0,0 +1,104 @@
  1942. +package Macro::Lists;
  1943. +
  1944. +use strict;
  1945. +use Carp::Assert;
  1946. +use Utils::ObjectList;
  1947. +use base qw(ObjectList);
  1948. +
  1949. +### CATEGORY: Class Lists
  1950. +
  1951. +##
  1952. +# Lists Macro::Lists->new()
  1953. +# Ensures:  $self->size() == 0
  1954. +#
  1955. +# Creates a new Lists object.
  1956. +sub new {
  1957. +   my ($class) = @_;
  1958. +   my $self = $class->SUPER::new();
  1959. +
  1960. +   $self->{nameIndex} = {};
  1961. +
  1962. +   return $self;
  1963. +}
  1964. +
  1965. +sub DESTROY {
  1966. +   my ($self) = @_;
  1967. +   Plugins::delHook($self->{hook}) if $self->{hook};
  1968. +   $self->clear();
  1969. +   $self->SUPER::DESTROY();
  1970. +}
  1971. +
  1972. +sub add {
  1973. +   my ($self, $member) = @_;
  1974. +
  1975. +   my $listIndex = $self->SUPER::add($member);
  1976. +   $member->{listIndex} = $listIndex;
  1977. +
  1978. +   my $indexSlot = $self->getNameIndexSlot($member->{name});
  1979. +   push @{$indexSlot}, $listIndex;
  1980. +
  1981. +   return $listIndex;
  1982. +}
  1983. +
  1984. +sub getByName {
  1985. +   my ($self, $name) = @_;
  1986. +   my $indexSlot = $self->{nameIndex}{lc($name)};
  1987. +   if ($indexSlot) {
  1988. +       return $self->get($indexSlot->[0]);
  1989. +   } else {
  1990. +       return undef;
  1991. +   }
  1992. +}
  1993. +
  1994. +sub remove {
  1995. +   my ($self, $member) = @_;
  1996. +
  1997. +   my $result = $self->SUPER::remove($member);
  1998. +   if ($result) {
  1999. +       my $indexSlot = $self->getNameIndexSlot($member->{name});
  2000. +       for (my $i = 0; $i < @{$indexSlot}; $i++) {
  2001. +           if ($indexSlot->[$i] == $member->{listIndex}) {
  2002. +               splice(@{$indexSlot}, $i, 1);
  2003. +               last;
  2004. +           }
  2005. +       }
  2006. +       if (@{$indexSlot} == 0) {
  2007. +           delete $self->{nameIndex}{lc($member->{name})};
  2008. +       }
  2009. +   }
  2010. +   return $result;
  2011. +}
  2012. +
  2013. +sub removeByName {
  2014. +   my ($self, $name) = @_;
  2015. +   my $member = $self->getByName($name);
  2016. +   if (defined $member) {
  2017. +       return $self->remove($member);
  2018. +   } else {
  2019. +       return 0;
  2020. +   }
  2021. +}
  2022. +
  2023. +# overloaded
  2024. +sub doClear {
  2025. +   my ($self) = @_;
  2026. +   $self->SUPER::doClear();
  2027. +   $self->{nameIndex} = {};
  2028. +}
  2029. +
  2030. +# overloaded
  2031. +sub checkValidity {
  2032. +   my ($self) = @_;
  2033. +   $self->SUPER::checkValidity();
  2034. +   foreach my $k (keys %{$self->{nameIndex}}) {
  2035. +       should(lc($self->getByName($k)->{name}), $k);
  2036. +       should(lc $k, $k);
  2037. +   }
  2038. +}
  2039. +
  2040. +sub getNameIndexSlot {
  2041. +   my ($self, $name) = @_;
  2042. +   return $self->{nameIndex}{lc($name)} ||= [];
  2043. +}
  2044. +
  2045. +1;
  2046. Index: Macro/Lists/Automacro.pm
  2047. ===================================================================
  2048. --- Macro/Lists/Automacro.pm    (revision 0)
  2049. +++ Macro/Lists/Automacro.pm    (working copy)
  2050. @@ -0,0 +1,32 @@
  2051. +#########################################################################
  2052. +#  OpenKore - Player actor object
  2053. +#  Copyright (c) 2005 OpenKore Team
  2054. +#
  2055. +#  TEST BY HENRYBK
  2056. +#
  2057. +#########################################################################
  2058. +package Macro::Lists::Automacro;
  2059. +
  2060. +use strict;
  2061. +use Globals;
  2062. +use Macro::Lists;
  2063. +use base qw(Macro::Lists);
  2064. +
  2065. +sub new {
  2066. +   my ($class) = @_;
  2067. +   my $self = $class->SUPER::new('Automacro');
  2068. +   #$self->{hooks} = Plugins::addHooks (['packet/stat_info2',        sub { $self->{state} = RECV_STAT_INFO2; }]);
  2069. +   return $self;
  2070. +}
  2071. +
  2072. +sub getByMacroCalled {
  2073. +   my ($self, $macroName) = @_;
  2074. +   foreach my $automacro (@{$self->getItems()}) {
  2075. +       if ($automacro->{parameters}{call} eq $macroName) {
  2076. +           return $automacro;
  2077. +       }
  2078. +   }
  2079. +   return undef;
  2080. +}
  2081. +
  2082. +1;
  2083. \ No newline at end of file
  2084. Index: Macro/Lists/Condition.pm
  2085. ===================================================================
  2086. --- Macro/Lists/Condition.pm    (revision 0)
  2087. +++ Macro/Lists/Condition.pm    (working copy)
  2088. @@ -0,0 +1,32 @@
  2089. +package Macro::Lists::Condition;
  2090. +
  2091. +use strict;
  2092. +use Carp::Assert;
  2093. +use Utils::ObjectList;
  2094. +use base qw(ObjectList);
  2095. +
  2096. +sub new {
  2097. +   my ($class) = @_;
  2098. +   my $self = $class->SUPER::new();
  2099. +
  2100. +   return $self;
  2101. +}
  2102. +
  2103. +sub DESTROY {
  2104. +   my ($self) = @_;
  2105. +   Plugins::delHook($self->{hook}) if $self->{hook};
  2106. +   $self->clear();
  2107. +   $self->SUPER::DESTROY();
  2108. +}
  2109. +
  2110. +sub add {
  2111. +   my ($self, $member) = @_;
  2112. +
  2113. +   my $listIndex = $self->SUPER::add($member);
  2114. +   $member->{listIndex} = $listIndex;
  2115. +
  2116. +   return $listIndex;
  2117. +}
  2118. +
  2119. +
  2120. +1;
  2121. Index: Macro/Lists/Macro.pm
  2122. ===================================================================
  2123. --- Macro/Lists/Macro.pm    (revision 0)
  2124. +++ Macro/Lists/Macro.pm    (working copy)
  2125. @@ -0,0 +1,21 @@
  2126. +#########################################################################
  2127. +#  OpenKore - Player actor object
  2128. +#  Copyright (c) 2005 OpenKore Team
  2129. +#
  2130. +#  TEST BY HENRYBK
  2131. +#
  2132. +#########################################################################
  2133. +package Macro::Lists::Macro;
  2134. +
  2135. +use strict;
  2136. +use Globals;
  2137. +use Macro::Lists;
  2138. +use base qw(Macro::Lists);
  2139. +
  2140. +sub new {
  2141. +   my ($class) = @_;
  2142. +   my $self = $class->SUPER::new('Macro');
  2143. +   return $self;
  2144. +}
  2145. +
  2146. +1;
  2147. \ No newline at end of file
  2148. Index: Macro/Macro.pm
  2149. ===================================================================
  2150. --- Macro/Macro.pm  (revision 0)
  2151. +++ Macro/Macro.pm  (working copy)
  2152. @@ -0,0 +1,16 @@
  2153. +package Macro::Macro;
  2154. +
  2155. +use strict;
  2156. +
  2157. +sub new {
  2158. +   my ($class, $name, $lines) = @_;
  2159. +   my $self = {
  2160. +       name => $name,
  2161. +       lines => $lines,
  2162. +       listIndex => -1
  2163. +   };
  2164. +   bless $self, $class;
  2165. +   return $self;
  2166. +}
  2167. +
  2168. +1;
  2169. \ No newline at end of file
  2170. Index: Macro/Parser.pm
  2171. ===================================================================
  2172. --- Macro/Parser.pm (revision 8992)
  2173. +++ Macro/Parser.pm (working copy)
  2174. @@ -6,8 +6,8 @@
  2175.  
  2176.  require Exporter;
  2177.  our @ISA = qw(Exporter);
  2178. -our @EXPORT = qw(parseMacroFile parseCmd isNewCommandBlock);
  2179. -our @EKSPORT_OK = qw(parseCmd isNewCommandBlock);
  2180. +our @EXPORT = qw(parseCmd);
  2181. +our @EKSPORT_OK = qw(parseCmd);
  2182.  
  2183.  use Globals;
  2184.  use Utils qw/existsInList/;
  2185. @@ -21,187 +21,6 @@
  2186.  
  2187.  our ($rev) = q$Revision: 6759 $ =~ /(\d+)/;
  2188.  
  2189. -my $tempmacro = 0;
  2190. -
  2191. -# adapted config file parser
  2192. -sub parseMacroFile {
  2193. -   my ($file, $no_undef) = @_;
  2194. -   unless ($no_undef) {
  2195. -       undef %macro;
  2196. -       undef %automacro;
  2197. -       undef @perl_name
  2198. -   }
  2199. -
  2200. -   my %block;
  2201. -   my $inBlock = 0;
  2202. -   my $macroCountOpenBlock = 0;
  2203. -   my ($macro_subs, @perl_lines);
  2204. -   open my $fp, "<:utf8", $file or return 0;
  2205. -   while (<$fp>) {
  2206. -       $. == 1 && s/^\x{FEFF}//; # utf bom
  2207. -       s/(.*)[\s\t]+#.*$/$1/;  # remove last comments
  2208. -       s/^\s*#.*$//;       # remove comments
  2209. -       s/^\s*//;       # remove leading whitespaces
  2210. -       s/\s*[\r\n]?$//g;   # remove trailing whitespaces and eol
  2211. -       s/  +/ /g;      # trim down spaces - very cool for user's string data?
  2212. -       next unless ($_);
  2213. -
  2214. -       if (!%block && /{$/) {
  2215. -           my ($key, $value) = $_ =~ /^(.*?)\s+(.*?)\s*{$/;
  2216. -           if ($key eq 'macro') {
  2217. -               %block = (name => $value, type => "macro");
  2218. -               $macro{$value} = []
  2219. -           } elsif ($key eq 'automacro') {
  2220. -               %block = (name => $value, type => "auto")
  2221. -           } elsif ($key eq 'sub') {
  2222. -               %block = (name => $value, type => "sub")
  2223. -           } else {
  2224. -               %block = (type => "bogus");
  2225. -               warning "$file: ignoring line '$_' in line $. (munch, munch, strange block)\n"
  2226. -           }
  2227. -           next
  2228. -       }
  2229. -
  2230. -       if (%block && $block{type} eq "macro") {
  2231. -           if ($_ eq "}") {
  2232. -               if ($macroCountOpenBlock) { # If the '}' is being used to terminate a block of commands from 'if'
  2233. -                   push(@{$macro{$block{name}}}, '}');
  2234. -                  
  2235. -                   if ($macroCountOpenBlock) {
  2236. -                       $macroCountOpenBlock--;
  2237. -                   }
  2238. -               } else {
  2239. -                   undef %block
  2240. -               }
  2241. -           } else {
  2242. -               if (isNewCommandBlock($_)) {
  2243. -                   $macroCountOpenBlock++
  2244. -               } elsif (!$macroCountOpenBlock && ($_ =~ /^}\s*else\s*{$/ || $_ =~ /}\s*elsif.*{$/ || $_ =~ /^case.*{$/ || $_ =~ /^else*{$/)) {
  2245. -                   warning "$file: ignoring '$_' in line $. (munch, munch, not found the open block command)\n";
  2246. -                   next
  2247. -               }
  2248. -
  2249. -               push(@{$macro{$block{name}}}, $_);
  2250. -           }
  2251. -          
  2252. -           next
  2253. -       }
  2254. -
  2255. -       if (%block && $block{type} eq "auto") {
  2256. -           if ($_ eq "}") {
  2257. -               if ($block{loadmacro}) {
  2258. -                   if ($macroCountOpenBlock) {
  2259. -                       push(@{$macro{$block{loadmacro_name}}}, '}');
  2260. -                      
  2261. -                       if ($macroCountOpenBlock) {
  2262. -                           $macroCountOpenBlock--;
  2263. -                       }
  2264. -                   } else {
  2265. -                       undef $block{loadmacro}
  2266. -                   }
  2267. -               } else {
  2268. -                   undef %block
  2269. -               }
  2270. -           } elsif ($_ eq "call {") {
  2271. -               $block{loadmacro} = 1;
  2272. -               $block{loadmacro_name} = "tempMacro".$tempmacro++;
  2273. -               $automacro{$block{name}}->{call} = $block{loadmacro_name};
  2274. -               $macro{$block{loadmacro_name}} = []
  2275. -           } elsif ($block{loadmacro}) {
  2276. -               if (isNewCommandBlock($_)) {
  2277. -                   $macroCountOpenBlock++
  2278. -               } elsif (!$macroCountOpenBlock && ($_ =~ /^}\s*else\s*{$/ || $_ =~ /}\s*elsif.*{$/ || $_ =~ /^case.*{$/ || $_ =~ /^else*{$/)) {
  2279. -                   warning "$file: ignoring '$_' in line $. (munch, munch, not found the open block command)\n";
  2280. -                   next
  2281. -               }
  2282. -
  2283. -               push(@{$macro{$block{loadmacro_name}}}, $_);
  2284. -           } else {
  2285. -               my ($key, $value) = $_ =~ /^(.*?)\s+(.*)/;
  2286. -               unless (defined $key) {
  2287. -                   warning "$file: ignoring '$_' in line $. (munch, munch, not a pair)\n";
  2288. -                   next
  2289. -               }
  2290. -               if ($amSingle{$key}) {
  2291. -                   $automacro{$block{name}}->{$key} = $value
  2292. -               } elsif ($amMulti{$key}) {
  2293. -                   push(@{$automacro{$block{name}}->{$key}}, $value)
  2294. -               } else {
  2295. -                   warning "$file: ignoring '$_' in line $. (munch, munch, unknown automacro keyword)\n"
  2296. -               }
  2297. -           }
  2298. -          
  2299. -           next
  2300. -       }
  2301. -      
  2302. -       if (%block && $block{type} eq "sub") {
  2303. -           if ($_ eq "}") {
  2304. -               if ($inBlock > 0) {
  2305. -                   push(@perl_lines, $_);
  2306. -                   $inBlock--;
  2307. -                   next
  2308. -               }
  2309. -               $macro_subs = join('', @perl_lines);
  2310. -               sub_execute($block{name}, $macro_subs);
  2311. -               push(@perl_name, $block{name}) unless existsInList(join(',', @perl_name), $block{name});
  2312. -               undef %block; undef @perl_lines; undef $macro_subs;
  2313. -               $inBlock = 0
  2314. -           }
  2315. -           elsif ($_ =~ /^}.*?{$/ && $inBlock > 0) {push(@perl_lines, $_)}
  2316. -           elsif ($_ =~ /{$/) {$inBlock++; push(@perl_lines, $_)}
  2317. -           else {push(@perl_lines, $_)}
  2318. -           next
  2319. -       }
  2320. -      
  2321. -       if (%block && $block{type} eq "bogus") {
  2322. -           if ($_ eq "}") {undef %block}
  2323. -           next
  2324. -       }
  2325. -
  2326. -       my ($key, $value) = $_ =~ /(?:^(.*?)\s|})+(.*)/;
  2327. -       unless (defined $key) {
  2328. -           warning "$file: ignoring '$_' in line $. (munch, munch, strange food)\n";
  2329. -           next
  2330. -       }
  2331. -
  2332. -       if ($key eq "!include") {
  2333. -           my $f = $value;
  2334. -           if (!File::Spec->file_name_is_absolute($value) && $value !~ /^\//) {
  2335. -               if ($file =~ /[\/\\]/) {
  2336. -                   $f = $file;
  2337. -                   $f =~ s/(.*)[\/\\].*/$1/;
  2338. -                   $f = File::Spec->catfile($f, $value)
  2339. -               } else {
  2340. -                   $f = $value
  2341. -               }
  2342. -           }
  2343. -           if (-f $f) {
  2344. -               my $ret = parseMacroFile($f, 1);
  2345. -               return $ret unless $ret
  2346. -           } else {
  2347. -               error "$file: Include file not found: $f\n";
  2348. -               return 0
  2349. -           }
  2350. -       }
  2351. -   }
  2352. -   #close $fp;
  2353. -   return 0 if %block;
  2354. -   return 1
  2355. -}
  2356. -
  2357. -sub sub_execute {
  2358. -   return if $Settings::lockdown;
  2359. -  
  2360. -   my ($name, $arg) = @_;
  2361. -   my $run = "sub ".$name." {".$arg."}";
  2362. -   eval($run);         # cycle the macro sub between macros only
  2363. -   $run = "eval ".$run;
  2364. -   Commands::run($run);        # exporting sub to the &main::sub, becarefull on your sub name
  2365. -                   # dont name your new sub equal to any &main::sub, you should take
  2366. -                   # the risk yourself.
  2367. -   message "[macro] registering sub $name ...\n", "menu";
  2368. -}
  2369. -
  2370.  # parses a text for keywords and returns keyword + argument as array
  2371.  # should be an adequate workaround for the parser bug
  2372.  #sub parseKw {
  2373. @@ -262,10 +81,10 @@
  2374.     my ($var, $tmp);
  2375.    
  2376.     # variables
  2377. -   $pre =~ s/(?:^|(?<=[^\\]))\$(\.?[a-z][a-z\d]*)/defined $varStack{$1} ? $varStack{$1} : ''/gei;
  2378. +   $pre =~ s/(?:^|(?<=[^\\]))\$(\.?[a-z][a-z\d]*)/$macroPlugin->isVarDefined($1) ? $macroPlugin->getVar($1) : ''/gei;
  2379.  =pod
  2380.     while (($var) = $pre =~ /(?:^|[^\\])\$(\.?[a-z][a-z\d]*)/i) {
  2381. -       $tmp = (defined $varStack{$var})?$varStack{$var}:"";
  2382. +       $tmp = $macroPlugin->isVarDefined($var) ? $macroPlugin->getVar($var):"";
  2383.         $var = q4rx $var;
  2384.         $pre =~ s/(^|[^\\])\$$var([^a-zA-Z\d]|$)/$1$tmp$2/g;
  2385.         last if defined $nick
  2386. @@ -273,10 +92,10 @@
  2387.  =cut
  2388.    
  2389.     # doublevars
  2390. -   $pre =~ s/\$\{(.*?)\}/defined $varStack{"#$1"} ? $varStack{"#$1"} : ''/gei;
  2391. +   $pre =~ s/\$\{(.*?)\}/$macroPlugin->isVarDefined("#$1") ? $macroPlugin->getVar("#$1") : ''/gei;
  2392.  =pod
  2393.     while (($var) = $pre =~ /\$\{(.*?)\}/i) {
  2394. -       $tmp = (defined $varStack{"#$var"})?$varStack{"#$var"}:"";
  2395. +       $tmp = ($macroPlugin->isVarDefined("#$var"))?$macroPlugin->getVar("#$var"):"";
  2396.         $var = q4rx $var;
  2397.         $pre =~ s/\$\{$var\}/$tmp/g
  2398.     }
  2399. @@ -362,15 +181,4 @@
  2400.     return $cmd
  2401.  }
  2402.  
  2403. -# check if on the line there commands that open new command blocks
  2404. -sub isNewCommandBlock {
  2405. -   my ($line) = @_;
  2406. -  
  2407. -   if ($line =~ /^if.*{$/ || $line =~ /^case.*{$/ || $line =~ /^switch.*{$/ || $line =~ /^else.*{$/) {
  2408. -       return 1;
  2409. -   } else {
  2410. -       return 0;
  2411. -   }
  2412. -}
  2413. -
  2414.  1;
  2415. Index: Macro/Plugin.pm
  2416. ===================================================================
  2417. --- Macro/Plugin.pm (revision 0)
  2418. +++ Macro/Plugin.pm (working copy)
  2419. @@ -0,0 +1,246 @@
  2420. +package Macro::Plugin;
  2421. +
  2422. +use strict;
  2423. +use Globals;
  2424. +use Log qw(message error warning);
  2425. +use base qw(Actor);
  2426. +use Macro::Data;
  2427. +use Macro::Lists;
  2428. +use Macro::Lists::Macro;
  2429. +use Macro::Lists::Automacro;
  2430. +use Macro::Utilities qw(callMacro);
  2431. +use Macro::Script;
  2432. +use Utils;
  2433. +
  2434. +sub new {
  2435. +   my ($class) = @_;
  2436. +   my $self = bless {}, $class;
  2437. +   $self->{macro} = new Macro::Lists::Macro();
  2438. +   $self->{automacro} = new Macro::Lists::Automacro();
  2439. +   $self->{macroVars} = {};
  2440. +   $self->{queue} = undef;
  2441. +   $self->{paused} = 0;
  2442. +   $self->{eventHooks} = {};
  2443. +   $self->{eventVariables} = {};
  2444. +   $self->{hooks} = [];
  2445. +   return $self;
  2446. +}
  2447. +
  2448. +sub cleanHooks {
  2449. +   my ($self) = @_;
  2450. +   foreach (@{$self->{hooks}}) {Plugins::delHook($_)}
  2451. +}
  2452. +
  2453. +sub reload {
  2454. +   my ($self) = @_;
  2455. +   $self->cleanHooks();
  2456. +   $self->{macro} = new Macro::Lists::Macro();
  2457. +   $self->{automacro} = new Macro::Lists::Automacro();
  2458. +   $self->{eventHooks} = undef;
  2459. +   $self->{eventVariables} = undef;
  2460. +   $self->{hooks} = undef;
  2461. +}
  2462. +
  2463. +sub isOnQueue {
  2464. +   my ($self) = @_;
  2465. +   return (defined $self->{queue})?1:0;
  2466. +}
  2467. +
  2468. +sub clearQueue {
  2469. +   my ($self) = @_;
  2470. +   undef $self->{queue} if defined $self->{queue};
  2471. +   message "macro queue cleared.\n";
  2472. +   return;
  2473. +}
  2474. +
  2475. +sub isPaused {
  2476. +   my ($self) = @_;
  2477. +   if (!defined $self->{queue}) {
  2478. +       warning "There's no macro currently running.\n";
  2479. +   } else {
  2480. +       return $self->{paused}?1:0;
  2481. +   }
  2482. +   return undef;
  2483. +}
  2484. +
  2485. +sub pauseMacro {
  2486. +   my ($self) = @_;
  2487. +   if (!defined $self->{queue}) {
  2488. +       warning "There's no macro currently running.\n";
  2489. +   } elsif ($self->{paused} == 1) {
  2490. +       warning "macro ".$self->{queue}->name." is already paused.\n";
  2491. +   } else {
  2492. +       $self->{paused} = 1;
  2493. +       message "macro ".$self->{queue}->name." paused.\n";
  2494. +   }
  2495. +   return;
  2496. +}
  2497. +
  2498. +sub resumeMacro {
  2499. +   my ($self) = @_;
  2500. +   if (!defined $self->{queue}) {
  2501. +       warning "There's no macro currently running.\n";
  2502. +   } elsif ($self->{paused} == 0) {
  2503. +       warning "macro ".$self->{queue}->name." is not paused.\n";
  2504. +   } else {
  2505. +       $self->{paused} = 0;
  2506. +       message "macro ".$self->{queue}->name." resumed.\n";
  2507. +   }
  2508. +   return;
  2509. +}
  2510. +
  2511. +# only adds hooks that are needed
  2512. +sub hookOnDemand {
  2513. +   my ($self) = @_;
  2514. +   my %firstHookHash;
  2515. +   my %firstVarHash;
  2516. +   my ($autoIndex, $autoPriority, $condIndex, %autoHooks, %autoVars);
  2517. +   foreach my $automacro (@{$self->{automacro}->getItems()}) {
  2518. +       $autoIndex = $automacro->{listIndex};
  2519. +       $autoPriority = $automacro->getParameter('priority');
  2520. +       if (exists $automacro->{hooks}) {
  2521. +           %autoHooks = %{$automacro->{hooks}};
  2522. +           while (my ($hook,$condIndexes) = each %autoHooks) {
  2523. +               $firstHookHash{$hook}{$autoIndex}{'autoIndex'} = $autoIndex;
  2524. +               $firstHookHash{$hook}{$autoIndex}{'priority'} = $autoPriority;
  2525. +               foreach my $condIndex (@{$condIndexes}) {
  2526. +                   push (@{$firstHookHash{$hook}{$autoIndex}{indexes}}, $condIndex);
  2527. +               }
  2528. +           }
  2529. +       }
  2530. +       if (exists $automacro->{variables}) {
  2531. +           %autoVars = %{$automacro->{variables}};
  2532. +           while (my ($varName,$condIndexes) = each %autoVars) {
  2533. +               $firstVarHash{$varName}{$autoIndex}{'autoIndex'} = $autoIndex;
  2534. +               $firstVarHash{$varName}{$autoIndex}{'priority'} = $autoPriority;
  2535. +               foreach my $condIndex (@{$condIndexes}) {
  2536. +                   push (@{$firstVarHash{$varName}{$autoIndex}{indexes}}, $condIndex);
  2537. +               }
  2538. +           }
  2539. +       }
  2540. +   } continue {
  2541. +       undef $autoIndex;
  2542. +       undef $condIndex;
  2543. +       undef $autoPriority;
  2544. +       undef %autoHooks;
  2545. +       undef %autoVars;
  2546. +   }
  2547. +
  2548. +   my @hookArray;
  2549. +   while (my ($hook,$autoIndexes) = each %firstHookHash) {
  2550. +       @hookArray = sort {$autoIndexes->{$a}->{'priority'} <=> $autoIndexes->{$b}->{'priority'}} keys %{$autoIndexes};
  2551. +       foreach (@hookArray) {
  2552. +           push (@{$self->{eventHooks}{$hook}}, $autoIndexes->{$_});
  2553. +       }
  2554. +       push(@{$self->{hooks}}, Plugins::addHook($hook, \&automacroCheck, $self));
  2555. +   }
  2556. +  
  2557. +   my @varArray;
  2558. +   while (my ($varName,$autoIndexes) = each %firstVarHash) {
  2559. +       @varArray = sort {$autoIndexes->{$a}->{'priority'} <=> $autoIndexes->{$b}->{'priority'}} keys %{$autoIndexes};
  2560. +       foreach (@varArray) {
  2561. +           push (@{$self->{eventVariables}{$varName}}, $autoIndexes->{$_});
  2562. +       }
  2563. +   }
  2564. +}
  2565. +
  2566. +sub isVarDefined {
  2567. +   my ($self, $varName) = @_;
  2568. +   return (exists $self->{macroVars}{$varName} && defined $self->{macroVars}{$varName});
  2569. +}
  2570. +
  2571. +sub existsVar {
  2572. +   my ($self, $varName) = @_;
  2573. +   return exists $self->{macroVars}{$varName};
  2574. +}
  2575. +
  2576. +sub getVar {
  2577. +   my ($self, $varName) = @_;
  2578. +   if (exists $self->{macroVars}{$varName}) {
  2579. +       return $self->{macroVars}{$varName};
  2580. +   } else {
  2581. +       return undef;
  2582. +   }
  2583. +}
  2584. +
  2585. +sub setVarValue {
  2586. +   my ($self, $varName, $varValue) = @_;
  2587. +   $self->{macroVars}{$varName} = $varValue;
  2588. +   if (exists $self->{eventVariables}{$varName}) {
  2589. +       &automacroCheck("var", {name => $varName, value => $varValue}, $self);
  2590. +   }
  2591. +}
  2592. +
  2593. +sub undefVar {
  2594. +   my ($self, $varName) = @_;
  2595. +   $self->{macroVars}{$varName} = undef;
  2596. +}
  2597. +
  2598. +sub deleteVar {
  2599. +   my ($self, $varName) = @_;
  2600. +   if (exists $self->{macroVars}{$varName}) {
  2601. +       delete $self->{macroVars}{$varName};
  2602. +   } else {
  2603. +       warning "[Macro] Variable $varName cannot be deleted because it doesn't exist";
  2604. +   }
  2605. +}
  2606. +
  2607. +sub automacroCheck {
  2608. +   my ($event, $args, $self) = @_;
  2609. +   my @returnedTrue;
  2610. +   my $returnTry;
  2611. +  
  2612. +  
  2613. +   use Data::Dumper;
  2614. +   open DUMP, ">:utf8", "dump.txt" or die $!;
  2615. +   print DUMP Dumper($self);
  2616. +   close(DUMP);
  2617. +  
  2618. +   if ($event ne "var") {
  2619. +       foreach my $automacro (@{$self->{eventHooks}{$event}}) {
  2620. +           $returnTry = 1;
  2621. +           foreach my $conditionIndex (@{$automacro->{indexes}}) {
  2622. +               unless ($self->{automacro}->get($automacro->{autoIndex})->{conditionList}->get($conditionIndex)->check($event,$args)) {
  2623. +                   $returnTry = 0;
  2624. +               }
  2625. +           }
  2626. +           if ($returnTry && $self->{automacro}->get($automacro->{autoIndex})->isActive()) {
  2627. +               push (@returnedTrue, $automacro->{autoIndex});
  2628. +           }
  2629. +       }
  2630. +   } else {
  2631. +       foreach my $automacro (@{$self->{eventVariables}{$args->{name}}}) {
  2632. +           $returnTry = 1;
  2633. +           foreach my $conditionIndex (@{$automacro->{indexes}}) {
  2634. +               unless ($self->{automacro}->get($automacro->{autoIndex})->{conditionList}->get($conditionIndex)->check($event,$args)) {
  2635. +                   $returnTry = 0;
  2636. +               }
  2637. +           }
  2638. +           if ($returnTry && $self->{automacro}->get($automacro->{autoIndex})->isActive()) {
  2639. +               push (@returnedTrue, $automacro->{autoIndex});
  2640. +           }
  2641. +       }
  2642. +   }
  2643. +  
  2644. +   return if (defined $self->{queue} && !$self->{queue}->interruptible);
  2645. +   foreach my $index (@returnedTrue) {
  2646. +       next unless ($self->{automacro}->get($index)->check());
  2647. +       undef $self->{queue} if defined $self->{queue};
  2648. +       $self->{queue} = new Macro::Script($self->{automacro}->get($index)->getParameter('call'));
  2649. +       if (defined $self->{queue}) {
  2650. +           $self->{queue}->overrideAI(1) if $self->{automacro}->get($index)->getParameter('overrideAI');
  2651. +           $self->{queue}->interruptible(0) if $self->{automacro}->get($index)->getParameter('exclusive');
  2652. +           $self->{queue}->orphan($self->{automacro}->get($index)->getParameter('orphan')) if $self->{automacro}->get($index)->getParameter('orphan');
  2653. +           $self->{queue}->timeout($self->{automacro}->get($index)->getParameter('delay')) if $self->{automacro}->get($index)->getParameter('delay');
  2654. +           $self->{queue}->setMacro_delay($self->{automacro}->get($index)->getParameter('macro_delay')) if $self->{automacro}->get($index)->getParameter('macro_delay');
  2655. +           $self->setVarValue(".caller", $self->{automacro}->get($index)->{name});
  2656. +           $self->{paused} = 0;
  2657. +           &callMacro;
  2658. +       } else {
  2659. +           error "unable to create macro queue.\n"
  2660. +       }
  2661. +       return;
  2662. +   }
  2663. +}
  2664. +
  2665. +1;
  2666. Index: Macro/Script.pm
  2667. ===================================================================
  2668. --- Macro/Script.pm (revision 8992)
  2669. +++ Macro/Script.pm (working copy)
  2670. @@ -10,7 +10,9 @@
  2671.  use Globals;
  2672.  use AI;
  2673.  use Macro::Data;
  2674. -use Macro::Parser qw(parseCmd isNewCommandBlock);
  2675. +use Macro::Plugin;
  2676. +use Macro::Parser qw(parseCmd);
  2677. +use Macro::FileParser qw(isNewCommandBlock);
  2678.  use Macro::Utilities qw(cmpr);
  2679.  use Macro::Automacro qw(releaseAM lockAM);
  2680.  use Log qw(message warning);
  2681. @@ -17,12 +19,14 @@
  2682.  
  2683.  our ($rev) = q$Revision: 6782 $ =~ /(\d+)/;
  2684.  
  2685. +my %macro;
  2686. +
  2687.  # constructor
  2688.  sub new {
  2689.     my ($class, $name, $repeat, $lastname, $lastline, $interruptible) = @_;
  2690.    
  2691.     $repeat = 0 unless ($repeat && $repeat =~ /^\d+$/);
  2692. -   return unless defined $macro{$name};
  2693. +   $macro{$name} = $macroPlugin->{macro}->getByName($name)->{'lines'};
  2694.     my $self = {
  2695.             name => $name,
  2696.             lastname => undef,
  2697. @@ -380,79 +384,38 @@
  2698.         $self->{line}++;
  2699.         $self->{timeout} = 0
  2700.     ##########################################
  2701. -   # pop value from variable: $var = [$list]
  2702. -   } elsif ($line =~ /^\$[a-z][a-z\d]*\s+=\s+\[\s*\$[a-z][a-z\d]*\s*\]$/i) {
  2703. -       if ($line =~ /;/) {run_sublines($line, $self); if (defined $self->{error}) {$self->{error} = "$errtpl: $self->{error}"; return}}
  2704. -       else {
  2705. -           my ($var, $list) = $line =~ /^\$([a-z][a-z\d]*?)\s+=\s+\[\s*\$([a-z][a-z\d]*?)\s*\]$/i;
  2706. -           my $listitems = ($varStack{$list} or "");
  2707. -           my $val;
  2708. -           if (($val) = $listitems =~ /^(.*?)(?:,|$)/) {
  2709. -               $listitems =~ s/^(?:.*?)(?:,|$)//;
  2710. -               $varStack{$list} = $listitems
  2711. -           }
  2712. -           else {$val = $listitems}
  2713. -           $varStack{$var} = $val;
  2714. -       }
  2715. -       $self->{line}++;
  2716. -       $self->{timeout} = 0 unless defined $self->{mainline_delay} && defined $self->{subline_delay};
  2717. -       return $self->{result} if $self->{result}
  2718. -   ##########################################
  2719.     # set variable: $variable = value
  2720.     } elsif ($line =~ /^\$[a-z]/i) {
  2721.         my ($var, $val);
  2722. -       if ($line =~ /;/) {run_sublines($line, $self); if (defined $self->{error}) {$self->{error} = "$errtpl: $self->{error}"; return}}
  2723. -       else {
  2724. +       if ($line =~ /;/) {run_sublines($line, $self); if (defined $self->{error}) {$self->{error} = "$errtpl: $self->{error}"; return}
  2725. +       } else {
  2726.             if (($var, $val) = $line =~ /^\$([a-z][a-z\d]*?)\s+=\s+(.*)/i) {
  2727.                 my $pval = parseCmd($val, $self);
  2728.                 if (defined $self->{error}) {$self->{error} = "$errtpl: $self->{error}"; return}
  2729.                 if (defined $pval) {
  2730. -                   if ($pval =~ /^\s*(?:undef|unset)\s*$/i && exists $varStack{$var}) {undef $varStack{$var}}
  2731. -                   else {$varStack{$var} = $pval}
  2732. +                   if ($pval =~ /^\s*(?:undef|unset)\s*$/i && $macroPlugin->existsVar($var)) {$macroPlugin->undefVar($var)}
  2733. +                   else {$macroPlugin->setVarValue($var, $pval);}
  2734.                 }
  2735.                 else {$self->{error} = "$errtpl: $val failed"}
  2736. -           }
  2737. -           elsif (($var, $val) = $line =~ /^\$([a-z][a-z\d]*?)([+-]{2})$/i) {
  2738. -               if ($val eq '++') {$varStack{$var} = ($varStack{$var} or 0)+1}
  2739. -               else {$varStack{$var} = ($varStack{$var} or 0)-1}
  2740. -           }
  2741. -           else {$self->{error} = "$errtpl: unrecognized assignment"}
  2742. -       }
  2743. -       $self->{line}++;
  2744. -       $self->{timeout} = 0 unless defined $self->{mainline_delay} && defined $self->{subline_delay};
  2745. -       return $self->{result} if $self->{result}
  2746. -   ##########################################
  2747. -   # set doublevar: ${$variable} = value
  2748. -   } elsif ($line =~ /^\$\{\$[.a-z]/i) {
  2749. -       my ($dvar, $val);
  2750. -       if ($line =~ /;/) {run_sublines($line, $self); if (defined $self->{error}) {$self->{error} = "$errtpl: $self->{error}"; return}}
  2751. -       else {
  2752. -           if (($dvar, $val) = $line =~ /^\$\{\$([.a-z][a-z\d]*?)\}\s+=\s+(.*)/i) {
  2753. -               my $var = $varStack{$dvar};
  2754. -               unless (defined $var) {$self->{error} = "$errtpl: $dvar not defined"}
  2755. -               else {
  2756. -                   my $pval = parseCmd($val, $self);
  2757. -                   if (defined $self->{error}) {$self->{error} = "$errtpl: $self->{error}"; return}
  2758. -                   unless (defined $pval) {$self->{error} = "$errtpl: $val failed"}
  2759. -                   else {
  2760. -                       if ($pval =~ /^\s*(?:undef|unset)\s*$/i) {undef $varStack{"#$var"}}
  2761. -                       else {$varStack{"#$var"} = $pval}
  2762. +           } elsif (($var, $val) = $line =~ /^\$([a-z][a-z\d]*?)([+-]{2})$/i) {
  2763. +               if ($val eq '++') {
  2764. +                   if ($macroPlugin->isVarDefined($var)) {
  2765. +                       $macroPlugin->setVarValue($var, ($macroPlugin->getVar($var)+1));
  2766. +                   } else {
  2767. +                       $macroPlugin->setVarValue($var, 1);
  2768.                     }
  2769. +               } else {
  2770. +                   if ($macroPlugin->isVarDefined($var)) {
  2771. +                       $macroPlugin->setVarValue($var, ($macroPlugin->getVar($var)-1));
  2772. +                   } else {
  2773. +                       $macroPlugin->setVarValue($var, -1);
  2774. +                   }
  2775.                 }
  2776. -           }
  2777. -           elsif (($dvar, $val) = $line =~ /^\$\{\$([.a-z][a-z\d]*?)\}([+-]{2})$/i) {
  2778. -               my $var = $varStack{$dvar};
  2779. -               unless (defined $var) {$self->{error} = "$errtpl: $dvar undefined"}
  2780. -               else {
  2781. -                   if ($val eq '++') {$varStack{"#$var"} = ($varStack{"#$var"} or 0)+1}
  2782. -                   else {$varStack{"#$var"} = ($varStack{"#$var"} or 0)-1}
  2783. -               }
  2784. -           }
  2785. -           else {$self->{error} = "$errtpl: unrecognized assignment."}
  2786. -       }
  2787. +           } else {$self->{error} = "$errtpl: unrecognized assignment"}
  2788.         $self->{line}++;
  2789.         $self->{timeout} = 0 unless defined $self->{mainline_delay} && defined $self->{subline_delay};
  2790.         return $self->{result} if $self->{result}
  2791. +       }
  2792.     ##########################################
  2793.     # label definition: :label
  2794.     } elsif ($line =~ /^:/) {
  2795. @@ -585,8 +548,8 @@
  2796.         } else {
  2797.             my @new_params = substr($cparms, 2) =~ /"[^"]+"|\S+/g;
  2798.             foreach my $p (1..@new_params) {
  2799. -               $varStack{".param".$p} = $new_params[$p-1];
  2800. -               $varStack{".param".$p} = substr($varStack{".param".$p}, 1, -1) if ($varStack{".param".$p} =~ /^".*"$/); # remove quotes
  2801. +               $macroPlugin->setVarValue(".param".$p,$new_params[$p-1]);
  2802. +               $macroPlugin->setVarValue(".param".$p,substr($macroPlugin->getVar(".param".$p), 1, -1)) if ($macroPlugin->getVar(".param".$p) =~ /^".*"$/);
  2803.             }
  2804.            
  2805.             $self->{subcall}->regSubmacro;
  2806. @@ -652,60 +615,35 @@
  2807.             $i++; next
  2808.         }
  2809.        
  2810. -       ##########################################
  2811. -       # pop value from variable: $var = [$list]
  2812. -       if ($e =~ /^\$[a-z][a-z\d]*\s+=\s+\[\s*\$[a-z][a-z\d]*\s*\]$/i) {
  2813. -           ($var, $list) = $e =~ /^\$([a-z][a-z\d]*?)\s+=\s+\[\s*\$([a-z][a-z\d]*?)\s*\]$/i;
  2814. -           my $listitems = ($varStack{$list} or "");
  2815. -           if (($val) = $listitems =~ /^(.*?)(?:,|$)/) {
  2816. -               $listitems =~ s/^(?:.*?)(?:,|$)//;
  2817. -               $varStack{$list} = $listitems
  2818. -           }
  2819. -           else {$val = $listitems}
  2820. -           $varStack{$var} = $val;
  2821. -           $i++; next
  2822. -              
  2823. +
  2824.         # set variable: $variable = value
  2825. -       } elsif ($e =~ /^\$[a-z]/i) {
  2826. +       if ($e =~ /^\$[a-z]/i) {
  2827.             if (($var, $val) = $e =~ /^\$([a-z][a-z\d]*?)\s+=\s+(.*)/i) {
  2828.                 my $pval = parseCmd($val, $self);
  2829.                 if (defined $self->{error}) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: $self->{error}"; last}
  2830.                 if (defined $pval) {
  2831. -                   if ($pval =~ /^\s*(?:undef|unset)\s*$/i && exists $varStack{$var}) {undef $varStack{$var}}
  2832. -                   else {$varStack{$var} = $pval}
  2833. +                   if ($pval =~ /^\s*(?:undef|unset)\s*$/i && $macroPlugin->existsVar($var)) {$macroPlugin->undefVar($var)}
  2834. +                   else {$macroPlugin->setVarValue($var,$pval)}
  2835.                 }
  2836.                 else {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: $e failed"; last}
  2837.             }
  2838.             elsif (($var, $val) = $e =~ /^\$([a-z][a-z\d]*?)([+-]{2})$/i) {
  2839. -               if ($val eq '++') {$varStack{$var} = ($varStack{$var} or 0)+1} else {$varStack{$var} = ($varStack{$var} or 0)-1}
  2840. -           }
  2841. -           else {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: unrecognized assignment in ($e)"; last}
  2842. -           $i++; next
  2843. -              
  2844. -       # set doublevar: ${$variable} = value
  2845. -       } elsif ($e =~ /^\$\{\$[.a-z]/i) {
  2846. -           if (($dvar, $val) = $e =~ /^\$\{\$([.a-z][a-z\d]*?)\}\s+=\s+(.*)/i) {
  2847. -               $var = $varStack{$dvar};
  2848. -               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}
  2849. -               else {
  2850. -                   my $pval = parseCmd($val, $self);
  2851. -                   if (defined $self->{error}) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: $self->{error}"; last}
  2852. -                   unless (defined $pval) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: $e failed"; last}
  2853. -                   else {
  2854. -                       if ($pval =~ /^\s*(?:undef|unset)\s*$/i) {undef $varStack{"#$var"}}
  2855. -                       else {$varStack{"#$var"} = $pval}
  2856. +               if ($val eq '++') {
  2857. +                   if ($macroPlugin->isVarDefined($var)) {
  2858. +                       $macroPlugin->setVarValue($var, ($macroPlugin->getVar($var)+1));
  2859. +                   } else {
  2860. +                       $macroPlugin->setVarValue($var, 1);
  2861.                     }
  2862. +               } else {
  2863. +                   if ($macroPlugin->isVarDefined($var)) {
  2864. +                       $macroPlugin->setVarValue($var, ($macroPlugin->getVar($var)-1));
  2865. +                   } else {
  2866. +                       $macroPlugin->setVarValue($var, -1);
  2867. +                   }
  2868.                 }
  2869.             }
  2870. -           elsif (($dvar, $val) = $e =~ /^\$\{\$([.a-z][a-z\d]*?)\}([+-]{2})$/i) {
  2871. -               $var = $varStack{$dvar};
  2872. -               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}
  2873. -               else {if ($val eq '++') {$varStack{"#$var"} = ($varStack{"#$var"} or 0)+1} else {$varStack{"#$var"} = ($varStack{"#$var"} or 0)-1}}
  2874. -               $i++; next
  2875. -           }
  2876.             else {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: unrecognized assignment in ($e)"; last}
  2877.             $i++; next
  2878. -              
  2879.         # stop command
  2880.         } elsif ($e eq "stop") {
  2881.             $self->{finished} = 1; last
  2882. Index: Macro/Utilities.pm
  2883. ===================================================================
  2884. --- Macro/Utilities.pm  (revision 8992)
  2885. +++ Macro/Utilities.pm  (working copy)
  2886. @@ -20,31 +20,31 @@
  2887.  
  2888.  # own ai_Isidle check that excludes deal
  2889.  sub ai_isIdle {
  2890. -   return 1 if $queue->overrideAI;
  2891. +   return 1 if $macroPlugin->{queue}->overrideAI;
  2892.  
  2893.     # now check for orphaned script object
  2894.     # may happen when messing around with "ai clear" and stuff.
  2895. -   if (defined $queue && !AI::inQueue('macro')) {
  2896. -       my $method = $queue->orphan;
  2897. +   if (defined $macroPlugin->{queue} && !AI::inQueue('macro')) {
  2898. +       my $method = $macroPlugin->{queue}->orphan;
  2899.  
  2900.         # 'terminate' undefs the macro object and returns "ai is not idle"
  2901.         if ($method eq 'terminate') {
  2902. -           undef $queue;
  2903. +           undef $macroPlugin->{queue};
  2904.             return 0
  2905.         # 'reregister' re-inserts "macro" in ai_queue at the first position
  2906.         } elsif ($method eq 'reregister') {
  2907. -           $queue->register;
  2908. +           $macroPlugin->{queue}->register;
  2909.             return 1
  2910.         # 'reregister_safe' waits until AI is idle then re-inserts "macro"
  2911.         } elsif ($method eq 'reregister_safe') {
  2912.             if (AI::isIdle || AI::is('deal')) {
  2913. -               $queue->register;
  2914. +               $macroPlugin->{queue}->register;
  2915.                 return 1
  2916.             }
  2917.             return 0
  2918.         } else {
  2919.             error "unknown 'orphan' method. terminating macro\n", "macro";
  2920. -           undef $queue;
  2921. +           undef $macroPlugin->{queue};
  2922.             return 0
  2923.         }
  2924.     }
  2925. @@ -142,7 +142,7 @@
  2926.         if ($text =~ /$1/ || ($2 eq 'i' && $text =~ /$1/i)) {
  2927.             if (!defined $cmpr) {
  2928.                 no strict;
  2929. -               foreach my $idx (1..$#-) {$varStack{".lastMatch$idx"} = ${$idx}}
  2930. +               foreach my $idx (1..$#-) {$macroPlugin->setVarValue(".lastMatch$idx",${$idx})}
  2931.                 use strict;
  2932.             }
  2933.             return 1
  2934. @@ -171,7 +171,7 @@
  2935.     if ($wordno =~ /^\$/) {
  2936.         my ($val) = $wordno =~ /^\$([a-zA-Z][a-zA-Z\d]*)\s*$/;
  2937.         return "" unless defined $val;
  2938. -       if (exists $varStack{$val} && $varStack{$val} =~ /^[1-9][0-9]*$/) {$wordno = $varStack{$val}}
  2939. +       if ($macroPlugin->existsVar($val) && $macroPlugin->getVar($val) =~ /^[1-9][0-9]*$/) {$wordno = $macroPlugin->getVar($val)}
  2940.         else {return ""}
  2941.    
  2942.     }
  2943. @@ -212,28 +212,32 @@
  2944.  sub refreshGlobal {
  2945.     my $var = $_[0];
  2946.  
  2947. -   $varStack{".time"} = time;
  2948. -   $varStack{".datetime"} = scalar localtime;
  2949. -   ($varStack{".second"}, $varStack{".minute"}, $varStack{".hour"}) = localtime;
  2950. +   $macroPlugin->setVarValue(".time", time);
  2951. +   $macroPlugin->setVarValue(".datetime", scalar localtime);
  2952. +   my ($sec, $min, $hour) = localtime;
  2953. +   $macroPlugin->setVarValue(".second", $sec);
  2954. +   $macroPlugin->setVarValue(".minute", $min);
  2955. +   $macroPlugin->setVarValue(".hour", $hour);
  2956.    
  2957.     return unless $net && $net->getState == Network::IN_GAME;
  2958.    
  2959. -   $varStack{".map"} = (defined $field)?$field->baseName:"undef";
  2960. -   my $pos = calcPosition($char); $varStack{".pos"} = sprintf("%d %d", $pos->{x}, $pos->{y});
  2961. +   $macroPlugin->setVarValue(".map", (defined $field)?$field->baseName:"undef");
  2962. +   my $pos = calcPosition($char);
  2963. +   $macroPlugin->setVarValue(".pos", sprintf("%d %d", $pos->{x}, $pos->{y}));
  2964.    
  2965. -   $varStack{".hp"} = $char->{hp};
  2966. -   $varStack{".sp"} = $char->{sp};
  2967. -   $varStack{".lvl"} = $char->{lv};
  2968. -   $varStack{".joblvl"} = $char->{lv_job};
  2969. -   $varStack{".spirits"} = ($char->{spirits} or 0);
  2970. -   $varStack{".zeny"} = $char->{zeny};
  2971. -   $varStack{".weight"} = $char->{weight};
  2972. -   $varStack{".maxweight"} = $char->{weight_max};
  2973. -   $varStack{'.status'} = (join ',',
  2974. +   $macroPlugin->setVarValue(".hp", $char->{hp});
  2975. +   $macroPlugin->setVarValue(".sp", $char->{sp});
  2976. +   $macroPlugin->setVarValue(".lvl", $char->{lv});
  2977. +   $macroPlugin->setVarValue(".joblvl", $char->{lv_job});
  2978. +   $macroPlugin->setVarValue(".spirits", ($char->{spirits} or 0));
  2979. +   $macroPlugin->setVarValue(".zeny", $char->{zeny});
  2980. +   $macroPlugin->setVarValue(".weight", $char->{weight});
  2981. +   $macroPlugin->setVarValue(".maxweight", $char->{weight_max});
  2982. +   $macroPlugin->setVarValue('.status', (join ',',
  2983.         ('muted')x!!$char->{muted},
  2984.         ('dead')x!!$char->{dead},
  2985.         map { $statusName{$_} || $_ } keys %{$char->{statuses}}
  2986. -   ) || 'none';
  2987. +   ) || 'none');
  2988.  }
  2989.  
  2990.  # get NPC array index
  2991. @@ -461,11 +465,11 @@
  2992.     if (defined $_[0]) {
  2993.         if ($_[0] ne '') {
  2994.             unless (Commands::run($command)) {
  2995. -               my $errorMsg = sprintf("[macro] %s failed with %s\n", $queue->name, $command);
  2996. +               my $errorMsg = sprintf("[macro] %s failed with %s\n", $macroPlugin->{queue}->name, $command);
  2997.                
  2998.                 my $hookArgs = {
  2999.                     'message' => $errorMsg,
  3000. -                   'name' => $queue->name,
  3001. +                   'name' => $macroPlugin->{queue}->name,
  3002.                     'error' => 'Commands::run failed',
  3003.                 };
  3004.                 Plugins::callHook ('macro/error', $hookArgs);
  3005. @@ -472,18 +476,18 @@
  3006.                 return $hookArgs->{continue} if $hookArgs->{return};
  3007.                
  3008.                 error $errorMsg, "macro";
  3009. -               undef $queue;
  3010. +               undef $macroPlugin->{queue};
  3011.                 return
  3012.             }
  3013.         }
  3014. -       $queue->ok;
  3015. -       if (defined $queue && $queue->finished) {undef $queue}
  3016. +       $macroPlugin->{queue}->ok;
  3017. +       if (defined $macroPlugin->{queue} && $macroPlugin->{queue}->finished) {undef $macroPlugin->{queue}}
  3018.     } else {
  3019. -       my $name = (defined $queue->{subcall}) ? $queue->{subcall}->name : $queue->name;
  3020. -       my $error = $queue->error;
  3021. +       my $name = (defined $macroPlugin->{queue}->{subcall}) ? $macroPlugin->{queue}->{subcall}->name : $macroPlugin->{queue}->name;
  3022. +       my $error = $macroPlugin->{queue}->error;
  3023.         my $errorMsg = sprintf(
  3024.             "[macro] %s error: %s\n",
  3025. -           $name =~ /^tempMacro\d+$/ && $varStack{'.caller'} ? $varStack{'.caller'}.'.call' : $name,
  3026. +           $name =~ /^tempMacro\d+$/ && $macroPlugin->isVarDefined('.caller') ? $macroPlugin->getVar('.caller').'.call' : $name,
  3027.             $error
  3028.         );
  3029.        
  3030. @@ -496,7 +500,7 @@
  3031.         return $hookArgs->{continue} if $hookArgs->{return};
  3032.        
  3033.         error $errorMsg, "macro";
  3034. -       undef $queue;
  3035. +       undef $macroPlugin->{queue};
  3036.         return
  3037.     }
  3038.    
  3039. @@ -505,25 +509,25 @@
  3040.  
  3041.  # macro/script
  3042.  sub callMacro {   
  3043. -   return unless defined $queue;
  3044. -   return if $onHold;
  3045. -   my %tmptime = $queue->timeout;
  3046. -   unless ($queue->registered || $queue->overrideAI) {
  3047. -       if (timeOut(\%tmptime)) {$queue->register}
  3048. +   return unless defined $macroPlugin->{queue};
  3049. +   return if $macroPlugin->isPaused();
  3050. +   my %tmptime = $macroPlugin->{queue}->timeout;
  3051. +   unless ($macroPlugin->{queue}->registered || $macroPlugin->{queue}->overrideAI) {
  3052. +       if (timeOut(\%tmptime)) {$macroPlugin->{queue}->register}
  3053.         else {return}
  3054.     }
  3055.     if (timeOut(\%tmptime) && ai_isIdle()) {
  3056.         do {
  3057. -           last unless processCmd $queue->next;
  3058. +           last unless processCmd $macroPlugin->{queue}->next;
  3059.             Plugins::callHook ('macro/callMacro/process');
  3060. -       } while !$onHold && $queue && $queue->macro_block;
  3061. +       } while $macroPlugin->{queue} && !$macroPlugin->isPaused() && $macroPlugin->{queue}->macro_block;
  3062.        
  3063.  =pod
  3064. -       # crashes when error inside macro_block encountered and $queue becomes undefined
  3065. -       my $command = $queue->next;
  3066. -       if ($queue->macro_block) {
  3067. -           while ($queue->macro_block) {
  3068. -               $command = $queue->next;
  3069. +       # crashes when error inside macro_block encountered and $macroPlugin->{queue} becomes undefined
  3070. +       my $command = $macroPlugin->{queue}->next;
  3071. +       if ($macroPlugin->{queue}->macro_block) {
  3072. +           while ($macroPlugin->{queue}->macro_block) {
  3073. +               $command = $macroPlugin->{queue}->next;
  3074.                 processCmd($command)
  3075.             }
  3076.         } else {
  3077. Index: Macro/Wx/Debugger.pm
  3078. ===================================================================
  3079. --- Macro/Wx/Debugger.pm    (revision 8992)
  3080. +++ Macro/Wx/Debugger.pm    (working copy)
  3081. @@ -102,19 +102,19 @@
  3082.  sub updateTool {
  3083.     my ($self) = @_;
  3084.    
  3085. -   $self->{toolbar}->EnableTool ($self->{tool}{go}, $onHold && defined $queue);
  3086. -   $self->{toolbar}->EnableTool ($self->{tool}{break}, !$onHold && defined $queue);
  3087. -   $self->{toolbar}->EnableTool ($self->{tool}{stop}, defined $queue);
  3088. -   $self->{toolbar}->EnableTool ($self->{tool}{stepInto}, $onHold && defined $queue);
  3089. -   $self->{toolbar}->EnableTool ($self->{tool}{stepOver}, $onHold && defined $queue);
  3090. -   $self->{toolbar}->EnableTool ($self->{tool}{stepOut}, $onHold && defined $queue);
  3091. +   $self->{toolbar}->EnableTool ($self->{tool}{go}, $macroPlugin->isPaused() && defined $macroPlugin->{queue});
  3092. +   $self->{toolbar}->EnableTool ($self->{tool}{break}, !$macroPlugin->isPaused() && defined $macroPlugin->{queue});
  3093. +   $self->{toolbar}->EnableTool ($self->{tool}{stop}, defined $macroPlugin->{queue});
  3094. +   $self->{toolbar}->EnableTool ($self->{tool}{stepInto}, $macroPlugin->isPaused() && defined $macroPlugin->{queue});
  3095. +   $self->{toolbar}->EnableTool ($self->{tool}{stepOver}, $macroPlugin->isPaused() && defined $macroPlugin->{queue});
  3096. +   $self->{toolbar}->EnableTool ($self->{tool}{stepOut}, $macroPlugin->isPaused() && defined $macroPlugin->{queue});
  3097.  }
  3098.  
  3099.  sub updateStatus {
  3100.     my ($self) = @_;
  3101.    
  3102. -   if (defined $queue) {
  3103. -       $self->{status}->SetStatusText ($onHold ? T('PAUSE') : T('RUN'), 1);
  3104. +   if (defined $macroPlugin->{queue}) {
  3105. +       $self->{status}->SetStatusText ($macroPlugin->isPaused() ? T('PAUSE') : T('RUN'), 1);
  3106.     } else {
  3107.         $self->{status}->SetStatusText (T('STOP'), 1);
  3108.     }
  3109. @@ -123,7 +123,7 @@
  3110.  sub updateSource {
  3111.     my ($self) = @_;
  3112.    
  3113. -   my $script = $queue or return;
  3114. +   my $script = $macroPlugin->{queue} or return;
  3115.     my @callStack;
  3116.     do {
  3117.         unshift @callStack, $script->name . ':' . $script->line;
  3118. @@ -176,8 +176,8 @@
  3119.             $self->{watch}->SetItemText ($i, $_);
  3120.         }
  3121.        
  3122. -       if ($varStack{$_} ne $self->{watch}->GetItem ($i, 1)->GetText) {
  3123. -           $self->{watch}->SetItem ($i, 1, $varStack{$_});
  3124. +       if ($macroPlugin->getVar($_) ne $self->{watch}->GetItem ($i, 1)->GetText) {
  3125. +           $self->{watch}->SetItem ($i, 1, $macroPlugin->getVar($_));
  3126.         }
  3127.        
  3128.         delete $self->{watchStack}{$_};
  3129. @@ -204,19 +204,19 @@
  3130.    
  3131.     undef $self->{step};
  3132.     undef $self->{stepLevel};
  3133. -   $onHold = 0;
  3134. +   $macroPlugin->isPaused() = 0;
  3135.  }
  3136.  
  3137.  sub macroError {
  3138.     my ($self, undef, $args) = @_;
  3139.    
  3140. -   $onHold = 1;
  3141. +   $macroPlugin->isPaused() = 1;
  3142.    
  3143.     $self->updateTool;
  3144.     $self->updateStatus;
  3145.     $self->{status}->SetStatusText ($args->{error}, 0);
  3146.    
  3147. -   my $script = $queue;
  3148. +   my $script = $macroPlugin->{queue};
  3149.     do {
  3150.         undef $script->{error};
  3151.         $script->{macro_block} = 0;
  3152. @@ -239,7 +239,7 @@
  3153.    
  3154.     $self->{status}->SetStatusText ('', 0);
  3155.    
  3156. -   unless (defined $queue) {
  3157. +   unless (defined $macroPlugin->{queue}) {
  3158.         $self->cleanup;
  3159.     } elsif ($self->{step}) {
  3160.         my $level = $self->subCallNesting;
  3161. @@ -250,7 +250,7 @@
  3162.         ) {
  3163.             undef $self->{step};
  3164.             undef $self->{stepLevel};
  3165. -           $onHold = 1;
  3166. +           $macroPlugin->isPaused() = 1;
  3167.         }
  3168.     }
  3169.    
  3170. @@ -273,8 +273,8 @@
  3171.  sub _onGo {
  3172.     my ($self) = @_;
  3173.    
  3174. -   if (defined $queue) {
  3175. -       $onHold = 0;
  3176. +   if (defined $macroPlugin->{queue}) {
  3177. +       $macroPlugin->isPaused() = 0;
  3178.        
  3179.         $self->updateTool;
  3180.         $self->updateStatus;
  3181. @@ -284,8 +284,8 @@
  3182.  sub _onBreak {
  3183.     my ($self) = @_;
  3184.    
  3185. -   if (defined $queue) {
  3186. -       $onHold = 1;
  3187. +   if (defined $macroPlugin->{queue}) {
  3188. +       $macroPlugin->isPaused() = 1;
  3189.        
  3190.         $self->updateTool;
  3191.         $self->updateStatus;
  3192. @@ -295,8 +295,8 @@
  3193.  sub _onStop {
  3194.     my ($self) = @_;
  3195.    
  3196. -   if (defined $queue) {
  3197. -       undef $queue;
  3198. +   if (defined $macroPlugin->{queue}) {
  3199. +       undef $macroPlugin->{queue};
  3200.         $self->cleanup;
  3201.        
  3202.         $self->updateTool;
  3203. @@ -307,9 +307,9 @@
  3204.  sub _onStepInto {
  3205.     my ($self) = @_;
  3206.    
  3207. -   if (defined $queue) {
  3208. +   if (defined $macroPlugin->{queue}) {
  3209.         $self->{step} = 'into';
  3210. -       $onHold = 0;
  3211. +       $macroPlugin->isPaused() = 0;
  3212.        
  3213.         $self->updateTool;
  3214.         $self->updateStatus;
  3215. @@ -319,10 +319,10 @@
  3216.  sub _onStepOver {
  3217.     my ($self) = @_;
  3218.    
  3219. -   if (defined $queue) {
  3220. +   if (defined $macroPlugin->{queue}) {
  3221.         $self->{step} = 'over';
  3222.         $self->{stepLevel} = $self->subCallNesting;
  3223. -       $onHold = 0;
  3224. +       $macroPlugin->isPaused() = 0;
  3225.        
  3226.         $self->updateTool;
  3227.         $self->updateStatus;
  3228. @@ -332,10 +332,10 @@
  3229.  sub _onStepOut {
  3230.     my ($self) = @_;
  3231.    
  3232. -   if (defined $queue) {
  3233. +   if (defined $macroPlugin->{queue}) {
  3234.         $self->{step} = 'out';
  3235.         $self->{stepLevel} = $self->subCallNesting;
  3236. -       $onHold = 0;
  3237. +       $macroPlugin->isPaused() = 0;
  3238.        
  3239.         $self->updateTool;
  3240.         $self->updateStatus;
  3241. @@ -362,8 +362,7 @@
  3242.     );
  3243.    
  3244.     return unless defined $value;
  3245. -  
  3246. -   $varStack{$key} = $value;
  3247. +   $macroPlugin->setVarValue($key, $value);
  3248.     $self->updateWatch;
  3249.  }
  3250.  
  3251. @@ -370,7 +369,7 @@
  3252.  sub changeLine {
  3253.     my ($self, $value) = @_;
  3254.    
  3255. -   if (defined $queue) {
  3256. +   if (defined $macroPlugin->{queue}) {
  3257.         $self->subCalledScript->{line} = $value;
  3258.        
  3259.         $self->updateSource;
  3260. @@ -378,13 +377,13 @@
  3261.  }
  3262.  
  3263.  sub subCalledScript {
  3264. -   my $script = $queue or return;
  3265. +   my $script = $macroPlugin->{queue} or return;
  3266.     $script = $script->{subcall} while $script->{subcall};
  3267.     return $script;
  3268.  }
  3269.  
  3270.  sub subCallNesting {
  3271. -   my $script = $queue or return 0;
  3272. +   my $script = $macroPlugin->{queue} or return 0;
  3273.     my $i = 1;
  3274.     while ($script->{subcall}) {
  3275.         $script = $script->{subcall};
Add Comment
Please, Sign In to add comment