使用方法:
1.將以下avoidSkill.pl程式碼,另存檔案為UTF-8編碼格式,檔案名稱命名為 avoidSkill.pl
2..放入 plugins 資料夾中
3.config.txt新增以下設定
avoidSkill 傳送之陣,病毒散撥,滑動陷阱,定位陷阱,魔耗陷阱,睡魔陷阱,霜凍陷阱,人孔 {
source
radius 6
method 1
step 5
}
avoidSkill 自我毀滅 {
# <要避免的技能名稱>
radius 5
# <要避免的技能的半徑範圍格數>
source Monster
# <施放者類型,Monster=魔物;Player=玩家。若二者都有則留空白。有分大小寫>
method 0
# <以下數字選一個>
# 0 - 隨機移動至半徑 <avoidSkill_#_radius> 以外 <avoidSkill_#_step> 格的地方
# 1 - 往施法點反方向移動 <avoidSkill_#_step> 格
# 2 - 移動至最接近的施法者
# 3 - 瞬移飛走(免服不適用)
# 4 - 攻擊施法者(只能用在魔物)
# 5 - 使用技能(只能用在魔物)
# (methods 0-1 的選項)
step 7
# <要移動多遠的格數>
# (method 5 的選項)
skill 後退迴避
# <用來對付魔物的技能>
lvl
# <技能等級>
isSelfSkill 1
# 技能是否用在自己身上
maxCastTime
# like normal skill slots
minCastTime
# like normal skill slots
}
===============以下為avoidSkill.pl程式碼==================
# avoidSkill by Joseph
# original code from MessyKoreXP
# licensed under GPL
package avoidSkill;
use strict;
#use warnings;
use Time::HiRes qw(time);
use Globals;
use Utils;
use Misc;
use Network::Send;
use Log qw(debug message warning error);
use Skill;
use encoding 'utf8';
Plugins::register('avoidSkill', 'React to skills.', \&onUnload);
my $hooks = Plugins::addHooks(
['is_casting', \&avoidSkill, undef],
['packet_skilluse', \&avoidSkill, undef]
);
sub onUnload {
Plugins::delHooks($hooks);
}
sub avoidSkill {
my (undef, $args) = @_;
my $sourceID = $args->{sourceID};
my $targetID = $args->{targetID};
my $skillID = $args->{skillID};
my $x = $args->{x};
my $y = $args->{y};
my $skill = new Skill(idn => $skillID);
$skill = $skill->getName();
my $source = Actor::get($sourceID);
debug "checking if we should avoid $skill from $source\n";
for (my $i = 0; exists $config{"avoidSkill_$i"}; $i++) {
next if (!$config{"avoidSkill_$i"});
if (existsInList($config{"avoidSkill_$i"}, $skill)) {
# if source is specified, make sure type is correct
next if ($config{"avoidSkill_$i"."_source"} && $config{"avoidSkill_$i"."_source"} ne $source->{actorType});
debug "checking avoid radius on $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{"avoidSkill_$i"."_radius"};
$right = $x + $config{"avoidSkill_$i"."_radius"};
$top = $y - $config{"avoidSkill_$i"."_radius"};
$bottom = $y + $config{"avoidSkill_$i"."_radius"};
$inRange = 1 if ($left <= $char->{pos_to}{x} && $right >= $char->{pos_to}{x} && $top <= $char->{pos_to}{y} && $bottom >= $char->{pos_to}{y});
} elsif ($targetID eq $accountID) {
$inRange = 1;
}
if ($inRange) {
if ($char->{sitting}) {
main::stand();
}
if ($config{"avoidSkill_$i"."_method"} == 0) {
my $found = 1;
my $count = 0;
my %move;
do {
($move{x}, $move{y}) = getRandPosition($config{"avoidSkill_${i}_step"});
$count++;
if ($count > 100) {
$found = 0;
last;
}
} while ($left <= $move{x} && $right >= $move{x} && $top <= $move{y} && $bottom >= $move{y});
if ($found) {
stopAttack();
sendMove(\$remote_socket, $move{x}, $move{y});
message "Avoid skill $skill, random move to $move{x}, $move{y}.\n";
}
} elsif ($config{"avoidSkill_$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{"avoidSkill_$i"."_step"})) + 1;
$random{y} = int(rand($config{"avoidSkill_$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) {
stopAttack();
sendMove(\$remote_socket, $move{x}, $move{y});
message "Avoid skill $skill, move to $move{x}, $move{y}.\n";
}
} elsif ($config{"avoidSkill_$i"."_method"} == 2) {
my %src;
$src{x} = $source->{pos_to}{x};
$src{y} = $source->{pos_to}{y};
my $found = 0;
my $count = 0;
my ($ex_left, $ex_right, $ex_top, $ex_bottom);
my ($in_left, $in_right, $in_top, $in_bottom);
my %move;
my %nearest;
do {
$ex_left = $src{'x'} - $count;
$ex_right = $src{'x'} + $count;
$ex_top = $src{'y'} - $count;
$ex_bottom = $src{'y'} + $count;
$count++;
$in_left = $src{'x'} - $count;
$in_right = $src{'x'} + $count;
$in_top = $src{'y'} - $count;
$in_bottom = $src{'y'} + $count;
my $nearest_dist = 9999;
for ($move{'y'} = $in_top; $move{'y'} <= $in_bottom; $move{'y'}++) {
for ($move{'x'} = $in_left; $move{'x'} <= $in_right; $move{'x'}++) {
if (($move{'x'} < $ex_left || $move{'x'} > $ex_right) && ($move{'y'} < $ex_top || $move{'y'} > $ex_bottom)) {
next if (($left <= $move{'x'} && $right >= $move{'x'} && $top <= $move{'y'} && $bottom >= $move{'y'}) ||
!($field->isWalkable($move{x}, $move{y})));
my $dist = distance(\%move, \%src);
if ($dist < $nearest_dist) {
$nearest_dist = $dist;
$nearest{'x'} = $move{'x'};
$nearest{'y'} = $move{'y'};
$found = 1;
}
}
}
}
} while (($count < 100) && (!$found));
if ($found) {
stopAttack();
sendMove(\$remote_socket, $nearest{x}, $nearest{y});
message "Avoid skill $skill, move to nearest position $nearest{'x'}, $nearest{'y'}.\n";
}
} elsif ($config{"avoidSkill_$i"."_method"} == 3) {
message "Avoid skill $skill, use random teleport.\n";
main::useTeleport(1);
} elsif ($config{"avoidSkill_$i"."_method"} == 4) {
return unless ($source->{actorType} eq 'Monster');
message "Avoid skill $skill, attack to $source->{name}\n";
# may not care about portal distance, oh well
stopAttack();
main::attack($sourceID);
} elsif ($config{"avoidSkill_$i"."_method"} == 5 && timeOut($AI::Timeouts::avoidSkill_skill, 3)) {
return unless ($source->{actorType} eq 'Monster');
message "Avoid skill $skill, use ".$config{"avoidSkill_$i"."_skill"}." to $source->{name}\n";
$skill = new Skill(name => $config{"avoidSkill_$i"."_skill"});
message "Use ".$skill->getHandle." on target\n";
if (main::ai_getSkillUseType($skill->getHandle)) {
my $pos = ($config{"avoidSkill_${i}_isSelfSkill"}) ? $char->{pos_to} : $monsters{$sourceID}{pos_to};
main::ai_skillUse(
$skill->getHandle,
$config{"avoidSkill_$i"."_lvl"},
$config{"avoidSkill_$i"."_maxCastTime"},
$config{"avoidSkill_$i"."_minCastTime"},
$pos->{x},
$pos->{y});
} else {
main::ai_skillUse(
$skill->getHandle,
$config{"avoidSkill_$i"."_lvl"},
$config{"avoidSkill_$i"."_maxCastTime"},
$config{"avoidSkill_$i"."_minCastTime"},
$config{"avoidSkill_${i}_isSelfSkill"} ? $accountID : $sourceID);
}
$AI::Timeouts::avoidSkill_skill = time;
}
}
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;
}
請多回覆唷,別讓此文沉掉了... |