Значит так, обьясню что я сделал, что плагин заработал.
Ну сначало просто скинул freecast.pl в соответствующую папку, попробовал не идёт пишет ошибку (см. скрин). И обратил внимание на выделеную уже мной строчку с надписью "line 18"
Дальше открыл в DzSoft Perl Editor этот файл, нашёл эту строчку(см второй скрин 18 строчка выделенная). Ну я и подумал, раз в этом дело, может там что то поменять?) я в настройках и созданиях плагинов полный нуб, поэтому стал просто всячески издеваться над словом Skills. Ну и проверял постоянно.
И ВДРУГ когда я просто стёр последнюю букву "s", сохранения и запуска бота, саг ЗАРАБОТАЛ! Значит причина была в этой строчке. Можно сказать мну повезло) и я рад)
Скидываю файл для других, пусть пользуются)
package freeCast;
# This plugin is licensed under the GNU GPL
# Copyright 2005 by kaliwanagan
# --------------------------------------------------
# How to install this thing..:
#
# The plugin will activate iff:
# you have the skill free cast at level 1 or higher, and
# attackUseWeapon is set to 1, and
# you are using an attackSkillSlot that has a cast bar
use strict;
use Plugins;
use Globals;
use Log qw(message warning error);
use AI;
use skill;
use Misc;
use Network;
use Network::Send;
use Utils;
use Math::Trig;
Plugins::register('Free Cast', 'experimental sage free cast support', \&Unload);
my $hook1 = Plugins::addHook('AI_post', \&call);
my $ID;
my $monster;
my %timeout;
sub Unload {
Plugins::delHook('AI_post', $hook1);
}
sub call {
my $i = AI::findAction("attack");
if (defined $i) {
my $args = AI::args($i);
$ID = $args->{ID};
$monster = $monsters{$ID};
}
if (AI::action eq "skill_use") {
cast();
}
}
sub cast {
if (($config{'attackUseWeapon'}) && ($char->{skills}{SA_FREECAST}{lv}) && main::timeOut(\%timeout)){
if(Utils::distance(main::calcPosition($char), main::calcPosition($monster)) <= ($config{"attackDistance"})) {
sendAttack(\$main::remote_socket, $monster->{ID}, ($config{'tankMode'}) ? 0 : 7);
} else {
my %attackhash = getAttackCoords(main::calcPosition($monster), main::calcPosition($char), ($config{"attackDistance"} - 1));
sendMove(\$main::remote_socket, $attackhash{x}, $attackhash{y});
}
}
$timeout{time} = time;
$timeout{timeout} = 1;
}
sub getAttackCoords {
my ($obj1, $obj2, $distance) = @_;
my %attack;
if ($$obj1{x} == $$obj2{x}) {
$attack{x} = $$obj2{x};
$attack{y} = ($$obj1{y} > $$obj2{y}) ? $$obj2{y} + $distance : $$obj2{y} - $distance;
return %attack;
}
if ($$obj1{y} == $$obj2{y}) {
$attack{y} = $$obj2{y};
$attack{x} = ($$obj1{x} > $$obj2{x}) ? $$obj2{x} + $distance : $$obj2{x} - $distance;
return %attack;
}
my $ang = atan(($$obj1{y} - $$obj2{y}) / ($$obj1{x} - $$obj2{x}));
$attack{x} = ($$obj1{x} > $$obj2{x}) ? $$obj2{x} + ($distance * cos($ang)) : $$obj2{x} - ($distance * cos($ang));
$attack{y} = ($$obj1{y} > $$obj2{y}) ? $$obj2{y} + ($distance * sin($ang)) : $$obj2{y} - ($distance * sin($ang));
return %attack;
};
return 1;
И файл тоже сам. Всем спасибо) я так РАД

