[Idle/Unsolved]Is this subroutine correct? [warp portal macro on command]

All about the macro plugin can be found in this forum. This forum is intended for the macro plugin only.

Moderator: Moderators

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

[Idle/Unsolved]Is this subroutine correct? [warp portal macro on command]

#1 Post by Darki »

[Edit] I've been a bit bored so I did my research and I think I made it right this time. The full macro would be like this:

Code: Select all

automacro warpPortal {
	console /^\(From: [name]\) : open warp$/i
	overrideAI 1
	call {

	# first a check for Blue Gems...

 		if (@invamount (Blue Gemstone) > 0) goto blue
		do pm "[name]" I need a Blue Gemstone.
		stop
	:blue
	
	# if we have, it stops AI so the macro isn't interrupted, then calls the subroutine to get the position for the portal.
	
		do ai manual
		$px = @arg("$.pos", 1)
		$py = @arg("$.pos", 2)
		$loc = warpPosition($px, $py)
		if ("$loc" == "none") goto noSkill

	# if we get a position it will cast the skill. If we don't get it, it's because there are obstacles, so better move your bot.
	# this might be improved in the future so it changes direction manually.

		do sl 27 $loc
		lock all; pause 2
		if (@eval (if (!$::char->{warp}{memo}[0]) {return 0}) == 0) goto fail
		release useWarp
	
	# from this point the bot will PM you the destinatiuons, and you can interrupt it if you want calling the second automacro.
		
		do pm "[name]" Those are my current saved maps:
			$i = 0
			while ($i <= 3) as warpLoop
			do pm "[name]" @eval ($i + 1) : @eval ($::char->{warp}{memo}[$i])
			$i++
		end warpLoop
		do pm "[name]" where to?
		pause 10
		
	# if we don't call a destination in 10 secs, it will close the warp automatically.
	# this might be changed in the future to add a parameter somewhere. <_<
	
		do pm "[name]" I guess you changed your mind...
		do warp cancel; goto ending
	:fail
	
	# message for when the skill couldn't be casted (like, delays, no SP, something.)
	
		do pm "[name]" Sorry, I couldn't cast the skill.
	:ending
	
	# AI is activated again, stuff is locked, etc.
	
		release all; lock useWarp; do ai on
		stop
	:noSkill

	# message for when there's no place for the skill.

		do pm "[name]" I don't have place for the skill.
		do ai on
	}
}

 automacro useWarp {
 	console /^\(From: [name]\) : (1st|2nd|3rd|4th|close) warp$/i
 	overrideAI 1
	call {
		lock useWarp
		if ($.lastMatch1 == "close") goto cancel
		
	# if you type "cancel" then the warp will be closed before the 10 secs pass. if you type one of the warps it will open it and repeat the destination.
		
		do eval my %_warp = ("1st", "0", "2nd", "1", "3rd", "2", "4th", "3");$::Macro::Data::varStack{dest} = $_warp{$::Macro::Data::varStack{".lastMatch1"}}
		do warp $dest
		do pm "[name]" Warp opened! Destination: @eval ($::maps_lut{$::char->{warp}{memo}[$dest].'.rsw'})!
		goto ending
	:cancel
		do pm "[name]" I guess you changed your mind...
		do warp cancel		
	:ending
	
	# AI is activated again, stuff is locked, etc.
	
		release all;lock useWarp; do ai on
	 }
}
Aaaand the subroutine to get the location is this one:

Code: Select all

sub warpPosition {

	my ($_px, $_py) = @_;

	my $_l = $::char->{look}{body};
	if (!defined $_l) {$_l = int(rand(8))};
	my @_areas = ( 
		[[0,4], [0,3],[-1,3],[1,3],[-1,4],[1,4],[-1,5],[1,5],[0,5],[0,2],[-1,2],[1,2],[-2,2],[2,2],[-2,3],[2,3],[-2,4],[2,4],[-2,5],[2,5],[-2,6],[2,6],[-1,6],[1,6],[0,6]] ,
		[[-3,3], [-3,2],[-2,3],[-4,3],[-3,4],[-2,2],[-3,1],[-1,3],[-4,2],[-2,4],[-5,3],[-3,5],[-4,4],[-2,1],[-1,2],[-3,0],[0,3],[-4,1],[-1,4],[-5,2],[-2,5],[-6,3],[-3,6],[-5,4],[-4,5]] ,
		[[-4,0], [-3,0],[-3,-1],[-3,1],[-4,-1],[-4,1],[-5,-1],[-5,1],[-5,0],[-2,0],[-2,-1],[-2,1],[-2,-2],[-2,2],[-3,-2],[-3,2],[-4,-2],[-4,2],[-5,-2],[-5,2],[-6,-2],[-6,2],[-6,-1],[-6,1],[-6,0]] ,
		[[-3,-3], [-2,-3],[-3,-2],[-3,-4],[-4,-3],[-2,-2],[-1,-3],[-3,-1],[-2,-4],[-4,-2],[-3,-5],[-5,-3],[-4,-4],[-1,-2],[-2,-1],[0,-3],[-3,0],[-1,-4],[-4,-1],[-2,-5],[-5,-2],[-3,-6],[-6,-3],[-4,-5],[-5,-4]] ,
		[[0,-4], [0,-3],[1,-3],[-1,-3],[1,-4],[-1,-4],[1,-5],[-1,-5],[0,-5],[0,-2],[1,-2],[-1,-2],[2,-2],[-2,-2],[2,-3],[-2,-3],[2,-4],[-2,-4],[2,-5],[-2,-5],[2,-6],[-2,-6],[1,-6],[-1,-6],[0,-6]] ,
		[[3,-3], [3,-2],[2,-3],[4,-3],[3,-4],[2,-2],[3,-1],[1,-3],[4,-2],[2,-4],[5,-3],[3,-5],[4,-4],[2,-1],[1,-2],[3,0],[0,-3],[4,-1],[1,-4],[5,-2],[2,-5],[6,-3],[3,-6],[5,-4],[4,-5]] ,
		[[4,0], [3,0],[3,1],[3,-1],[4,1],[4,-1],[5,1],[5,-1],[5,0],[2,0],[2,1],[2,-1],[2,2],[2,-2],[3,2],[3,-2],[4,2],[4,-2],[5,2],[5,-2],[6,2],[6,-2],[6,1],[6,-1],[6,0]] ,
		[[3,3],[2,3],[3,2],[3,4],[4,3],[2,2],[1,3],[3,1],[2,4],[4,2],[3,5],[5,3],[4,4],[1,2],[2,1],[0,3],[3,0],[1,4],[4,1],[2,5],[5,2],[3,6],[6,3],[4,5],[5,4]]
	);

	my @_area = @{@_areas[$_l]};
	my $_skip;
	
	foreach my $_z (@_area) {
		my ($_x, $_y) = ($_px + $_z->[0], $_py + $_z->[1]);
		next if (!$::field->isWalkable($_x, $_y));
		next if (!Misc::checkLineWalkable({x => $_px, y => $_py},{x => $_x, y => $_y}, 0));
		$_skip = 0;
		foreach my $_npc (@{$::npcsList->getItems()}) {
			next if ($_npc->{pos_to}{x} != $_x || $_npc->{pos_to}{y} != $_y);
			$_skip = 1;
			last;
		}
		next if ($_skip == 1);
		foreach my $_pl (@{$::playersList->getItems()}) {
			next if ($_pl->{pos_to}{x} != $_x || $_pl->{pos_to}{y} != $_y);
			$_skip = 1;
			last;
		}
		next if ($_skip == 1);
		foreach my $_mon (@{$::monstersList->getItems()}) {
			next if ($_mon->{pos_to}{x} != $_x || $_mon->{pos_to}{y} != $_y);
			$_skip = 1;
			last;
		}
		next if ($_skip == 1);
		return $_x." ".$_y;
	}
	return "none";
}
Basically if it finds a good location it will return it, and if not it will return "none". This subroutine will check a location 4 squares ahead of the bot in the direction it's looking, for obstacles, LoS and people/NPCs/monsters on it. In case it's occupied, it will start checking locations in a 5x5 area around this initial point, so unless you're facing a very huge obstacle, the subroutine will always find a place to use the portal.

I've noticed that I usually failed the locations in my previous "versions" of this macro because for some reason the $::char->{pos} doesn't give me the correct position unless I do a south/north/east/etc command, so I had to use the macro $.pos variable, that apparently works fine. I didn't test this too well yet, I hope somebody interested helps me to get errors. I'll test it myself for some time and post it in the topic I opened long ago for it.
ImageImageImage
ImageImageImage
ImageImageImage