Protect The Priest Macro=)

Moderator: Moderators

Message
Author
Hexo55
Noob
Noob
Posts: 8
Joined: 19 Jan 2010, 22:57
Noob?: Yes

Re: Protect The Priest Macro=)

#21 Post by Hexo55 »

Ok I added some codes to this macro. Here is what it does:

1. If there is a monster attacking the priest, the priest will PM the master the monster's location
2. The master, after receiving the monster's location will calculate and get the monster's ID nearest to that location. (Attacking the monster nearest the Priest is another option, but if the attacking monster is using ranged attack or there are too many monsters near the master and the priest, this will not work)

Note: That this is still not tested so use it at your own risk. Update to the latest macro version first since subroutine functionality is needed.

Code: Select all

################################
######PROTECT ME################
################################

automacro ProtectMe {
	timeout 8
	console /Monster (.*) \((\d+)\) attacks you/
	call {

		$mymap = $.map
		$lockmap = @config (lockMap)
		$master = @config (followTarget)
		$mon = $.lastMatch2
		$monlocation = 0

		if ($mymap == $lockmap) goto help
		:help
		
		#get monster's location
		$monlocation = get_monster_location("$mon")
		do pm "$master" xd $monlocation
		if ($mymap != $lockmap) goto stop
		:stop
		stop
	}
}

#get monster location
sub get_monster_location {
	my ($target_id) = @_;

	foreach (@{$monstersList->getItems()}) {
		if ($_->{binID} == $target_id) {
			return "$_->{pos_to}{x} $_->{pos_to}{y}";
		} 
	}
}



################################
######COMMAND###################
################################

automacro Command {
	console /\(From: (.*)\) : xd (\d+) (\d+)/
	call {
#####NOTE : edit $town to the map you are using storage and auto buys!####
		$town = Geffen #edit this!
		$mymap = $.map
		$xd = $.lastMatch1
		$xd2 = $.lastMatch2
		$xd3 = $.lastMatch3
		
		#get the monster nearest to the pm'ed location
		$targetmon = monster_near_loc("$xd2", "$xd3")
		if ($mymap == $town) goto DeadMa
		do a $targetmon
		pause 0.5
		do pm "$xd" I'll protect you..
		stop
		:DeadMa
		stop
	}
}

sub monster_near_loc {
	my ($target_x, $target_y) = @_;
	my $min_distance = 20;
	my $distance;
	my $target_monster = 0;
	
	foreach (@{$monstersList->getItems()}) {
		$distance = get_distance("$target_x", "$target_y", "$_->{pos_to}{x}", "$->{pos_to}{y}");
		if ($distance < $min_distance) {
			$min_distance = $distance;
			$target_monster = $_->{binID};  
		}	
	}

	return $target_monster;
}


sub get_distance {
	my ($x1, $y1, $x2, $y2) = @_;			
	my $line_x = abs($x1 - $x2);
	my $line_y = abs($y1 - $y2);
	my $distance = sqrt($line_x ** 2 + $line_y ** 2);
	
	return $distance;
}
[EDIT]
changed

Code: Select all

my ($x1, $y1, $x1, $y2) = @_;
to

Code: Select all

my ($x1, $y1, $x2, $y2) = @_;
inside sub get_distance

I guess this is the problem why sub monster_near_loc failed
Last edited by Hexo55 on 06 Mar 2010, 06:25, edited 5 times in total.

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

Re: Protect The Priest Macro=)

#22 Post by ezza »

@Hexo55 - nice macro with sub... but you should be aware of the logic flows. Especially for...

Code: Select all

      if ($mymap == $lockmap) goto help
      :help
and...

Code: Select all

      if ($mymap != $lockmap) goto stop
      :stop


p.s: I believe there must be something missing in between both samples. I mean, if the if statement returns false, both samples will go to the next line is it? So, whats the use of using jumping (if statement there) ? I dont get it ;)

Hexo55
Noob
Noob
Posts: 8
Joined: 19 Jan 2010, 22:57
Noob?: Yes

Re: Protect The Priest Macro=)

#23 Post by Hexo55 »

Hmmm, sorry for that. I didn't do anything much with the automacro part, I edited only those that are related with the subs. Anyway, if I have the time, I'll post a new one. ;)

MiDaM
Human
Human
Posts: 35
Joined: 20 Jan 2010, 09:07
Noob?: Yes

Re: Protect The Priest Macro=)

#24 Post by MiDaM »

Hexo55 wrote:Ok I added some codes to this macro. Here is what it does:

1. If there is a monster attacking the priest, the priest will PM the master the monster's location
2. The master, after receiving the monster's location will calculate and get the monster's ID nearest to that location. (Attacking the monster nearest the Priest is another option, but if the attacking monster is using ranged attack or there are too many monsters near the master and the priest, this will not work)

Note: That this is still not tested so use it at your own risk. Update to the latest macro version first since subroutine functionality is needed.

Code: Select all

################################
######PROTECT ME################
################################

automacro ProtectMe {
	timeout 8
	console /Monster (.*) \((\d+)\) attacks you/
	call {

		$mymap = $.map
		$lockmap = @config (lockMap)
		$master = @config (followTarget)
		$mon = $.lastMatch2
		$monlocation = 0

		if ($mymap == $lockmap) goto help
		:help
		
		#get monster's location
		$monlocation = get_monster_location("$mon")
		do pm "$master" xd $monlocation
		if ($mymap != $lockmap) goto stop
		:stop
		stop
	}
}

#get monster location
sub get_monster_location {
	my ($target_id) = @_;

	foreach (@{$monstersList->getItems()}) {
		if ($_->{binID} == $target_id) {
			return "$_->{pos_to}{x} $_->{pos_to}{y}";
		} 
	}
}



################################
######COMMAND###################
################################

automacro Command {
	console /\(From: (.*)\) : xd (\d+) (\d+)/
	call {
#####NOTE : edit $town to the map you are using storage and auto buys!####
		$town = Geffen #edit this!
		$mymap = $.map
		$xd = $.lastMatch1
		$xd2 = $.lastMatch2
		$xd3 = $.lastMatch3
		
		#get the monster nearest to the pm'ed location
		$targetmon = monster_near_loc("$xd2", "$xd3");
		if ($mymap == $town) goto DeadMa
		do a $targetmon
		pause 0.5
		do pm "$xd" I'll protect you..
		stop
		:DeadMa
		stop
	}
}

sub monster_near_loc {
	my ($target_x, $target_y) = @_;
	my $min_distance = 20;
	my $distance;
	my $target_monster = 0;
	
	foreach (@{$monstersList->getItems()}) {
		$distance = get_distance("$target_x", "$target_y", "$_->{pos_to}{x}", "$->{pos_to}{y}");
		if ($distance < $min_distance) {
			$min_distance = $distance;
			$target_monster = $_->{binID};  
		}	
	}

	return $target_monster;
}


sub get_distance {
	my ($x1, $y1, $x1, $y2) = @_;			
	my $line_x = abs($x1 - $x2);
	my $line_y = abs($y1 - $y2);
	my $distance = sqrt($line_x ** 2 + $line_y ** 2);
	
	return $distance;
}
I Have a Erreur :(

Code: Select all

[macro] automacro Command triggered.
[macro] tempMacro1 error: error in 5: Error in line 5: $targetmon = monster_near_loc("$xd2", "$xd3");
[macro] tempMacro1 error in sub-line 0: $targetmon = monster_near_loc("$xd2", "$xd3") failed
Image

Hexo55
Noob
Noob
Posts: 8
Joined: 19 Jan 2010, 22:57
Noob?: Yes

Re: Protect The Priest Macro=)

#25 Post by Hexo55 »

Hmm, weird error. I don't know why the sub monster_near_loc failed. It's not a syntax error, but try removing the semicolon in this line

Code: Select all

$targetmon = monster_near_loc("$xd2", "$xd3");
and see if that works. Some relevant logs may also be useful. Are you always having this kind of error?

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

Re: Protect The Priest Macro=)

#26 Post by ezza »

@Hexo55 - the perl sub in macro plugins has its limitation to the global var and functionality. If you want to call certain function inside OK, what you need to do is to teach the perl sub where you can get the function... like what the given samples did here.

From the 2 samples... no 1 used sub existsInList that cycle inside macro plugins (I teach macro with my own sub...for example) but the no 2 used existsInList function inside OK (Utils::existsInList($guild, $guildName)) to do the job.

So, I hope that you could see the different with both examples and try to adapt the idea into yours. Maybe you could use &main::OK Function or else.... Good luck ;)

Hexo55
Noob
Noob
Posts: 8
Joined: 19 Jan 2010, 22:57
Noob?: Yes

Re: Protect The Priest Macro=)

#27 Post by Hexo55 »

I'm currently trying to digest what you said ezza. I'm pretty slow sometimes ;) . Correct me if I'm wrong, but are you saying that we can't use "custom macro subs" inside "custom macro subs"? So the one causing the problem is this line here inside monster_near_loc():

Code: Select all

$distance = get_distance("$target_x", "$target_y", "$_->{pos_to}{x}", "$->{pos_to}{y}");
Hmm, maybe I could use Utils::distance() instead.

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

Re: Protect The Priest Macro=)

#28 Post by ezza »

Code: Select all

$distance = get_distance("$target_x", "$target_y", "$_->{pos_to}{x}", "$->{pos_to}{y}")
Note: The line above could be used inside macro line or macro perl sub if you already have the get_distance perl sub-routine.


the get_distance here is your new perl sub name... you must teach the macro plugins what exactly the get_distance is to be. In the other words... write the perl yourself... yes, you can use your custom macro perl sub inside both macro line and macro perl sub. But, if you want to use OK source function... you have to teach the macro where the function is located... as for me, usually i use &main::function_name if I want to recall the function. For example...

Code: Select all

$distance = &main::get_distance("$target_x", "$target_y", "$_->{pos_to}{x}", "$->{pos_to}{y}");
Note: this is perl sub line... strictly not for macro line




p.s: I hope you understand what i'm saying... ;)

Hexo55
Noob
Noob
Posts: 8
Joined: 19 Jan 2010, 22:57
Noob?: Yes

Re: Protect The Priest Macro=)

#29 Post by Hexo55 »

Ok I think I got it now. So, macro perl subs cannot directly see other macro perl subs unless we reference it using &main::function_name. Is that correct? I'll edit the code to reflect what you suggested, thanks for helping out. ;)

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

Re: Protect The Priest Macro=)

#30 Post by ezza »

Nope... example:

Code: Select all

sub get {
   ...;
   return 0 if bla bla;
   return 1
}
the sub get above could be used directly inside macro line or macro perl sub line since you already told the macro plugins what exactly you want to do with that function...

Code: Select all

macro example {
   ...
   ...
   $x = get(blabla) #sub get here
   log \$x = $x
   $y = test()
   log \$y = $y
}
sub test {
   my $x = 1;
   my $y = get(blabla); #and here 
   return 0 if ($x < $y);
   return 1
}

The above macro and perl sub is just for example purpose... might not working :) . But the point here is... once you registered the sub get into macro plugins... you can now use it freely anywhere in your macro script.

Post Reply