How to avoid traps by monsters?

International

Moderator: Moderators

Message
Author
ro123
Noob
Noob
Posts: 2
Joined: 30 Nov 2010, 04:16
Noob?: Yes

How to avoid traps by monsters?

#1 Post by ro123 »

Hey guys, I currently leave my char in Amatsu maze 3f, where there'r lots of shinobis and, they use claymore traps!!!
It really hurts on my bots. So i'm wondering if there is a way to automatically avoid those traps?

Thank you!

Cloud
Plain Yogurt
Plain Yogurt
Posts: 86
Joined: 09 Apr 2008, 13:39

Re: How to avoid traps by monsters?

#2 Post by Cloud »

make a macro to avoid traps, don't ask how read the manual.

sofax222
Developers
Developers
Posts: 214
Joined: 24 Nov 2010, 03:08
Noob?: Yes

Re: How to avoid traps by monsters?

#3 Post by sofax222 »

This is my plugin code, "avoidTrap.pl":

Code: Select all

package avoidTrap;

use strict;
#use warnings;

use Time::HiRes qw(time);

use Globals;
use Utils;
use Misc;
use AI;
use Network::Send;
use Commands;
use Log qw(debug message warning error);
use Skill;
use Translation;
use encoding 'utf8';

our $lasttime = time;
our $dirTurn = 1;

Plugins::register('avoidTrap', 'React to traps.', \&on_unload, \&on_reload);

my $hooks = Plugins::addHooks(['AI_pre', \&AI_hook]);

my $prefix = "avoidTrap_";
my $prefix2 = "_afterCast";

sub on_unload {
	Plugins::delHooks($hooks);
}

sub on_reload {
	message "avoidTrap plugin reloading\n";
	Plugins::delHooks($hooks);
}

sub AI_hook {
	AI::dequeue if(AI::action eq "avoidtrap" && !$config{autoAvoidTrap});
	return if (!$config{autoAvoidTrap});
	my $timeout = $config{avoidTrapTimeout} ? $config{avoidTrapTimeout} : 1;
	if (timeOut($lasttime, $timeout)) {
		checkGroundTrap();
		$lasttime = time;
	}
}

sub checkGroundTrap {
	for my $ID (@spellsID) {
		my $spell = $spells{$ID};
		next unless $spell;
		avoidTrap('AI_hook', {
			'skill' => getSpellName($spell->{type}),
			'skillID' => $spell->{type},
			'x' => $spell->{pos}{x},
			'y' => $spell->{pos}{y}
		});
	}
}

sub avoidTrap {
	my (undef, $args) = @_;
	my $hookName = shift;
	my $skill = $args->{skill};
	my $skillID = $args->{skillID};
	my $x = $args->{x};
	my $y = $args->{y};
	my $i = 0;
	my $pos = calcPosition($char);

	debug "checking if we should avoid $skill at ($x, $y)\n";
#	message T("1--- $skill\n");

	for (my $i = 0; exists $config{"avoidTrap_$i"}; $i++) {
		next if (!$config{"avoidTrap_$i"});

		if (existsInList($config{"avoidTrap_$i"}, $skill)) {

			debug "checking avoid radius on $skill\n";
#			message T("2--- $skill\n");

			# check if we are inside the skill area of effect
			my $inRange;
			my ($left,$right,$top,$bottom);
			if ($x != 0 || $y != 0) {
				$left = $x - $config{"avoidTrap_$i"."_radius"};
				$right = $x + $config{"avoidTrap_$i"."_radius"};
				$top = $y - $config{"avoidTrap_$i"."_radius"};
				$bottom = $y + $config{"avoidTrap_$i"."_radius"};
				$inRange = 1 if ($left <= $pos->{x} && $right >= $pos->{x} && $top <= $pos->{y} && $bottom >= $pos->{y});
			}

			if ($inRange) {
				if ($char->{sitting}) {
					main::stand();
				}

				#   Methods (choose one)
				#   0 - Random position outside <avoidTrap_#_radius> by <avoidTrap_#_step>
				#   1 - Move to opposite side by <avoidTrap_#_step>
				#   2 - Move the right or left side.
				#   3 - Teleport

				if ($config{"avoidTrap_$i"."_method"} == 0) {
					my $found = 1;
					my $count = 0;
					my %move;
					do {
						($move{x}, $move{y}) = getRandPosition($config{"avoidTrap_${i}_step"});
						$count++;
						if ($count > 100) {
							$found = 0;
							last;
						}
					} while ($left <= $move{x} && $right >= $move{x} && $top <= $move{y} && $bottom >= $move{y});

					if ($found) {
						$char->stopAttack();
						sendMove(\$remote_socket, $move{x}, $move{y});
						message "-- Avoid trap $skill, random move to $move{x}, $move{y}.\n";
					}

				} elsif ($config{"avoidTrap_$i"."_method"} == 1) {
					my $dx = $x - $char->{pos_to}{x};
					my $dy = $y - $char->{pos_to}{y};
					my %random;
					my %move;

					my $found = 1;
					my $count = 0;
					do {
						$random{x} = int(rand($config{"avoidTrap_$i"."_step"})) + 1;
						$random{y} = int(rand($config{"avoidTrap_$i"."_step"})) + 1;

						if ($dx >= 0) {
							$move{x} = $char->{pos_to}{x} - $random{x};
						} else {
							$move{x} = $char->{pos_to}{x} + $random{x};
						}

						if ($dy >= 0) {
							$move{y} = $char->{pos_to}{y} - $random{y};
						} else {
							$move{y} = $char->{pos_to}{y} + $random{y};
						}

						$count++;
						if ($count > 100) {
							$found = 0;
							last;
						}
					} while (!($field->isWalkable($x, $y)));

					if ($found) {
						$char->stopAttack();
						sendMove(\$remote_socket, $move{x}, $move{y});
						message "-- Avoid trap $skill, move to $move{x}, $move{y}.\n";
					}

				} elsif ($config{"avoidTrap_$i"."_method"} == 2) {
					my $found = 1;
					my $count = 0;
					my %move;
					($move{x}, $move{y}) = getSidePosition($config{"avoidTrap_${i}_step"}, $x, $y, $pos->{x}, $pos->{y});

					$char->stopAttack();
					sendMove(\$remote_socket, $move{x}, $move{y});
					message "-- Avoid trap $skill ($x, $y), random move from ($pos->{x}, $pos->{y}) to ($move{x}, $move{y}).\n";

				} elsif ($config{"avoidTrap_$i"."_method"} == 3) {
					message "-- Avoid trap $skill, use random teleport.\n";
					main::useTeleport(1);
				}

			}

			last;
		}
	}
}

sub getRandPosition {
	my $range = shift;
	my $x_pos = shift;
	my $y_pos = shift;
	my $x_rand;
	my $y_rand;
	my $x;
	my $y;

	if ($x_pos eq "" || $y_pos eq "") {
		$x_pos = $char->{'pos_to'}{'x'};
		$y_pos = $char->{'pos_to'}{'y'};
	}

	do {
		$x_rand = int(rand($range)) + 1;
		$y_rand = int(rand($range)) + 1;

		if (int(rand(2))) {
			$x = $x_pos + $x_rand;
		} else {
			$x = $x_pos - $x_rand;
		}

		if (int(rand(2))) {
			$y = $y_pos + $y_rand;
		} else {
			$y = $y_pos - $y_rand;
		}
	} while (!($field->isWalkable($x, $y)));

	my @ret = ($x, $y);
	return @ret;
}

sub getSidePosition {
	my $range = shift;
	my $x2 = shift;
	my $y2 = shift;
	my $x1 = shift;
	my $y1 = shift;

	if ($x1 eq "" || $y1 eq "") {
		my $pos = calcPosition($char);
		$x1 = $pos->{x};
		$y1 = $pos->{y};
	}

	my $a = 0.0;
	my $dx = 0;
	my $dy = $range;
	if ($y1 != $y2) {
		$a = ($x2 - $x1) / ($y1 - $y2);
		$dx = $range / sqrt(1 + $a * $a);
		$dy = $a * $dx;
	}

	my $x;
	my $y;
#	my $dd;

#	if (int(rand(2))) {
#		$dd = 1;
#	} else {
#		$dd = -1;
#	}

	$x = $x1 + int($dirTurn * $dx);
	$y = $y1 + int($dirTurn * $dy);

	if (!($field->isWalkable($x, $y))) {
		$dirTurn = -1 * $dirTurn;
		$x = $x1 + int($dirTurn * $dx);
		$y = $y1 + int($dirTurn * $dy);
	}
	my @ret = ($x, $y);
	return @ret;
}

1;
Setting in config.txt:

Code: Select all

autoAvoidTrap 1
avoidTrapTimeout 1

avoidTrap <trap names> {
	label myPlug_T0
	radius 5
	method 2
	step 6
}

But, it not works 100%.
I am working for improving it !

jclopez
Noob
Noob
Posts: 5
Joined: 22 Dec 2010, 09:56
Noob?: Yes

Re: How to avoid traps by monsters?

#4 Post by jclopez »

I tried your plugin.. the problem is it cannot detect traps that are already exist in the ground.

sofax222
Developers
Developers
Posts: 214
Joined: 24 Nov 2010, 03:08
Noob?: Yes

Re: How to avoid traps by monsters?

#5 Post by sofax222 »

jclopez wrote:I tried your plugin.. the problem is it cannot detect traps that are already exist in the ground.
I don't kown why you can not work.
My kore could detect the traps on ground.
But not always can avoid the trap successly.
The following is my new code:

Code: Select all

# avoidTrap by Snoopy

package avoidTrap;

use strict;
#use warnings;

use Time::HiRes qw(time);

use Globals;
use Utils;
use Misc;
use AI;
use Network::Send;
use Commands;
use Log qw(debug message warning error);
use Skill;
use Translation;
use encoding 'utf8';

our $lasttime = time;
our $dirTurn = 1;

Plugins::register('avoidTrap', 'React to traps.', \&on_unload, \&on_reload);

my $hooks = Plugins::addHooks(['AI_pre', \&AI_hook]);

my $prefix = "avoidTrap_";
my $prefix2 = "_afterCast";

sub on_unload {
	Plugins::delHooks($hooks);
}

sub on_reload {
	message "avoidTrap plugin reloading\n";
	Plugins::delHooks($hooks);
}

sub AI_hook {
	return if (!$config{autoAvoidTrap});
	my $timeout = $config{avoidTrapTimeout} ? $config{avoidTrapTimeout} : 1;
	if (timeOut($lasttime, $timeout)) {
		checkGroundTrap();
		$lasttime = time;
	}
}

sub checkGroundTrap {
	for my $ID (@spellsID) {
		my $spell = $spells{$ID};
		my $binID = $spell->{binID};
		next unless $spell;
		if (!$spell->{mark}) {
			$spell->{mark} = 1;
#			avoidTrap('AI_hook', {
#				'binID' => $binID,
#				'skill' => getSpellName($spell->{type}),
#				'skillID' => $spell->{type},
#				'x' => $spell->{pos}{x},
#				'y' => $spell->{pos}{y}
#			});
			last if (avoidTrap('AI_hook', {
				'binID' => $binID,
				'skill' => getSpellName($spell->{type}),
				'skillID' => $spell->{type},
				'x' => $spell->{pos}{x},
				'y' => $spell->{pos}{y}
			}));
		}
	}
}

sub avoidTrap {
	my (undef, $args) = @_;
	my $hookName = shift;
	my $binID = $args->{binID};
	my $skill = $args->{skill};
	my $skillID = $args->{skillID};
	my $x = $args->{x};
	my $y = $args->{y};
	my $i = 0;
	my $pos = calcPosition($char);
	my $ret = 0;

	debug "checking if we should avoid $skill at ($x, $y)\n";
#	message T("1--- $skill\n");

	for (my $i = 0; exists $config{"avoidTrap_$i"}; $i++) {
		next if (!$config{"avoidTrap_$i"});

		if (existsInList($config{"avoidTrap_$i"}, $skill)) {

			debug "checking avoid radius on $skill\n";
#			message T("2--- $skill\n");

			# check if we are inside the skill area of effect
			my $inRange;
			my ($left,$right,$top,$bottom);
			if ($x != 0 || $y != 0) {
				$left = $x - $config{"avoidTrap_$i"."_radius"};
				$right = $x + $config{"avoidTrap_$i"."_radius"};
				$top = $y - $config{"avoidTrap_$i"."_radius"};
				$bottom = $y + $config{"avoidTrap_$i"."_radius"};
				$inRange = 1 if ($left <= $pos->{x} && $right >= $pos->{x} && $top <= $pos->{y} && $bottom >= $pos->{y});
			}

			if ($inRange) {
				if ($char->{sitting}) {
					main::stand();
				}

				#   Methods (choose one)
				#   0 - Random position outside <avoidTrap_#_radius> by <avoidTrap_#_step>
				#   1 - Move to opposite side by <avoidTrap_#_step>
				#   2 - Move the right or left side.
				#   3 - Teleport
				#   5 - Use skill. (monsters only)

				if ($config{"avoidTrap_$i"."_method"} == 0) {
					my $found = 1;
					my $count = 0;
					my %move;
					do {
						($move{x}, $move{y}) = getRandPosition($config{"avoidTrap_${i}_step"});
						$count++;
						if ($count > 100) {
							$found = 0;
							last;
						}
					} while ($left <= $move{x} && $right >= $move{x} && $top <= $move{y} && $bottom >= $move{y});

					if ($found) {
						$char->stopAttack();
						sendMove(\$remote_socket, $move{x}, $move{y});
						message "-- Avoid trap $skill, random move to $move{x}, $move{y}.\n";
					}

				} elsif ($config{"avoidTrap_$i"."_method"} == 1) {
					my $dx = $x - $char->{pos_to}{x};
					my $dy = $y - $char->{pos_to}{y};
					my %random;
					my %move;

					my $found = 1;
					my $count = 0;
					do {
						$random{x} = int(rand($config{"avoidTrap_$i"."_step"})) + 1;
						$random{y} = int(rand($config{"avoidTrap_$i"."_step"})) + 1;

						if ($dx >= 0) {
							$move{x} = $char->{pos_to}{x} - $random{x};
						} else {
							$move{x} = $char->{pos_to}{x} + $random{x};
						}

						if ($dy >= 0) {
							$move{y} = $char->{pos_to}{y} - $random{y};
						} else {
							$move{y} = $char->{pos_to}{y} + $random{y};
						}

						$count++;
						if ($count > 100) {
							$found = 0;
							last;
						}
					} while (!($field->isWalkable($x, $y)));

					if ($found) {
						$char->stopAttack();
						sendMove(\$remote_socket, $move{x}, $move{y});
						message "-- Avoid trap $skill, move to $move{x}, $move{y}.\n";
						$ret = 1;
					}

				} elsif ($config{"avoidTrap_$i"."_method"} == 2) {
					my $found = 1;
					my $count = 0;
					my %move;
					($move{x}, $move{y}) = getSidePosition($config{"avoidTrap_${i}_step"}, $x, $y, $pos->{x}, $pos->{y});

					$char->stopAttack();
					sendMove(\$remote_socket, $move{x}, $move{y});
					message "- Avoid trap $skill [$binID] ($x, $y), random move from ($pos->{x}, $pos->{y}) to ($move{x}, $move{y}).\n";
					$ret = 1;

				} elsif ($config{"avoidTrap_$i"."_method"} == 3) {
					message "-- Avoid trap $skill, use random teleport.\n";
					main::useTeleport(1);
					$ret = 1;

				} elsif ($config{"avoidTrap_$i"."_method"} == 5 && timeOut($AI::Timeouts::avoidTrap_skill, 3)) {
					message "Avoid trap $skill, use ".$config{"avoidTrap_$i"."_skill"}." from ($x, $y)\n";

					$skill = new Skill(name => $config{"avoidTrap_$i"."_skill"});

#					message "Use ".$skill->getHandle."\n";

					if (main::ai_getSkillUseType($skill->getHandle)) {
						my $pos = $char->{pos_to};
						main::ai_skillUse(
							$skill->getHandle,
							$config{"avoidTrap_$i"."_lvl"},
							$config{"avoidTrap_$i"."_maxCastTime"},
							$config{"avoidTrap_$i"."_minCastTime"},
							$pos->{x},
							$pos->{y});
					} else {
						main::ai_skillUse(
							$skill->getHandle,
							$config{"avoidTrap_$i"."_lvl"},
							$config{"avoidTrap_$i"."_maxCastTime"},
							$config{"avoidTrap_$i"."_minCastTime"},
							$accountID);
					}
					$AI::Timeouts::avoidTrap_skill = time;
					$ret = 1;
				}

			}

			last;
		}
	}
	return $ret;
}

sub getRandPosition {
	my $range = shift;
	my $x_pos = shift;
	my $y_pos = shift;
	my $x_rand;
	my $y_rand;
	my $x;
	my $y;

	if ($x_pos eq "" || $y_pos eq "") {
		$x_pos = $char->{'pos_to'}{'x'};
		$y_pos = $char->{'pos_to'}{'y'};
	}

	do {
		$x_rand = int(rand($range)) + 1;
		$y_rand = int(rand($range)) + 1;

		if (int(rand(2))) {
			$x = $x_pos + $x_rand;
		} else {
			$x = $x_pos - $x_rand;
		}

		if (int(rand(2))) {
			$y = $y_pos + $y_rand;
		} else {
			$y = $y_pos - $y_rand;
		}
	} while (!($field->isWalkable($x, $y)));

	my @ret = ($x, $y);
	return @ret;
}

sub getSidePosition {
	my $range = shift;
	my $x2 = shift;
	my $y2 = shift;
	my $x1 = shift;
	my $y1 = shift;

	if ($x1 eq "" || $y1 eq "") {
		my $pos = calcPosition($char);
		$x1 = $pos->{x};
		$y1 = $pos->{y};
	}

	my $a = 0.0;
	my $dx = 0;
	my $dy = $range;
	if ($y1 != $y2) {
		$a = ($x2 - $x1) / ($y1 - $y2);
		$dx = $range / sqrt(1 + $a * $a);
		$dy = $a * $dx;
	}

	my $x;
	my $y;
#	my $dd;

#	if (int(rand(2))) {
#		$dd = 1;
#	} else {
#		$dd = -1;
#	}

	$x = $x1 + int($dirTurn * $dx);
	$y = $y1 + int($dirTurn * $dy);

	if (!($field->isWalkable($x, $y))) {
		$dirTurn = -1 * $dirTurn;
		$x = $x1 + int($dirTurn * $dx);
		$y = $y1 + int($dirTurn * $dy);
	}
	my @ret = ($x, $y);
	return @ret;
}

1;
You clould add some "message" statements in to the "AI_hook" subroutine, to test the "'AI_pre" event hook.
So thing like:

Code: Select all

......................
sub AI_hook {
	message "the step 1 of avoidTrap hook !\n";
	return if (!$config{autoAvoidTrap});
	message "the step 2 of avoidTrap hook (to check the flag of autoAvoidTrap) ! \n";
	my $timeout = $config{avoidTrapTimeout} ? $config{avoidTrapTimeout} : 1;
	if (timeOut($lasttime, $timeout)) {
		checkGroundTrap();
		$lasttime = time;
	}
}
......................

unholysin
Noob
Noob
Posts: 15
Joined: 30 Jul 2012, 09:35
Noob?: No

Re: How to avoid traps by monsters?

#6 Post by unholysin »

i have tried your plugins , i still died by claymore trap , and after die its has error .. still having a hard time avoiding traps , can anyone help ? thanks

sofax222
Developers
Developers
Posts: 214
Joined: 24 Nov 2010, 03:08
Noob?: Yes

Re: How to avoid traps by monsters?

#7 Post by sofax222 »

and after die its has error ..
What error ?

PS: It is not 100% to avoid successly !

Post Reply