handsFree - свободные клетки (для портала итд)

Дополнения к OpenKore, расширяющиее её функциональность, называются плагинами.

Модератор: 4epT

EternalHarvest
Разработчик
Сообщения: 819
Зарегистрирован: Пн окт 27, 2008 9:49 pm

handsFree - свободные клетки (для портала итд)

Сообщение EternalHarvest »

Код: Выделить всё

# free выполняет команду, подставляя вместо ~ случайные координаты свободной клетки вокруг бота
do free sl 27 ~
pause 1
do warp 1
# freer подставляет последние использованные координаты
do freer move ~
handsFree.pl:
  1. package handsFree;
  2. use strict;
  3.  
  4. #########################################################################
  5. #  handsFree OpenKore plugin v1.0 by EternalHarvest
  6. #########################################################################
  7.  
  8. use Globals;
  9. use Log qw(message);
  10. use Commands;
  11.  
  12. use constant DEFAULT_SPREAD => 7;
  13.  
  14. my $spread = defined $::config{'handsFree_spread'} ? $::config{'handsFree_spread'} : DEFAULT_SPREAD;
  15.  
  16. Plugins::register ('handsFree', 'Find free cell', \&unload);
  17. my $cmds = Commands::register (
  18.     ["free", "Perform command at free cell", \&handsFree],
  19.     ["freer", "Perform command on last free cell", \&handsFreeRepeat]
  20. );
  21. sub unload {
  22.     Commands::unregister ($cmds);
  23. }
  24.  
  25. my ($lastX, $lastY);
  26.  
  27. sub handsFreeAction {
  28.     my (@reach, @dead, $x, $y, $a, $b, $m, $n);
  29.     my $s;
  30.     my $count = ($spread*2+1) ** 2 - 1;
  31.    
  32.     for ($x = $char->{pos}{x}-$spread; $x <= $char->{pos}{x}+$spread; $x++) {
  33.         for ($y = $char->{pos}{y}-$spread; $y <= $char->{pos}{y}+$spread; $y++) {
  34.             $count -= !($reach[$x][$y] = $field->isWalkable ($x, $y));
  35.         }
  36.     }
  37.    
  38.     for ($m = -1; $m < 2; $m += 2) {
  39.         for ($n = -1; $n < 2; $n += 2) {
  40.             for ($x = 0; $x <= $spread; $x++) {
  41.                 for ($y = 0; $y <= $spread; $y++) {
  42.                     next if $dead[$char->{pos}{x} + $x*$m][$char->{pos}{y} + $y*$n] || $reach[$char->{pos}{x} + $x*$m][$char->{pos}{y} + $y*$n];
  43.                     for ($a = $x; $a <= $spread; $a++) {
  44.                         for ($b = $y; $b <= $spread; $b++) {
  45.                             $count -= $reach[$char->{pos}{x} + $a*$m][$char->{pos}{y} + $b*$n];
  46.                             $reach[$char->{pos}{x} + $a*$m][$char->{pos}{y} + $b*$n] = 0;
  47.                             $dead[$char->{pos}{x} + $a*$m][$char->{pos}{y} + $b*$n] = 1;
  48.                         }
  49.                     }
  50.                 }
  51.             }
  52.         }
  53.     }
  54.    
  55.     foreach my $actor (
  56.         @{$monstersList->getItems ()},
  57.         @{$playersList->getItems ()},
  58.         @{$petsList->getItems ()},
  59.         @{$npcsList->getItems ()}
  60.     ) {
  61.         $count -= $reach[$actor->{pos}{x}][$actor->{pos}{y}];
  62.         $reach[$actor->{pos}{x}][$actor->{pos}{y}] = 0;
  63.     }
  64.    
  65.     $reach[$char->{pos}{x}][$char->{pos}{y}] = 0;
  66.    
  67.     if ($count > 0) {
  68.         until ($reach[$x][$y]) {
  69.             $x = $char->{pos}{x} + int (rand ($spread*2 + 1)) - $spread;
  70.             $y = $char->{pos}{y} + int (rand ($spread*2 + 1)) - $spread;
  71.         }
  72.     } else {
  73.         $x = 0; $y = 0;
  74.         message "handsFree: no available cells!\n";
  75.     }
  76.    
  77.     $lastX = $x; $lastY = $y;
  78. }
  79.  
  80. sub handsFree {
  81.     shift;
  82.     my $params = shift;
  83.    
  84.     handsFreeAction ();
  85.    
  86.     if ($params && $lastX) {
  87.         $params =~ s/~/$lastX $lastY/;
  88.         Commands::run ($params);
  89.     }
  90. }
  91.  
  92. sub handsFreeRepeat {
  93.     shift;
  94.     my $params = shift;
  95.    
  96.     if ($params && $lastX) {
  97.         $params =~ s/~/$lastX $lastY/;
  98.         Commands::run ($params);
  99.     }
  100. }
  101.  
  102. 1;
Аватара пользователя
kLabMouse
Профессионал
Сообщения: 4776
Зарегистрирован: Вс ноя 05, 2006 4:32 pm

Re: handsFree - свободные клетки (для портала итд)

Сообщение kLabMouse »

:)
Неплохо.
Но курс начинающего Плагинописателя здан на 3-ечку.
Нихарашо делать кучу вложеных цыклов. Ибо любой язык програмирования, на любой платформе таким боком тормознёш по полной.

А так, браво!!! :Bravo:
Аватара пользователя
Cooot
Грамотный
Сообщения: 306
Зарегистрирован: Пт апр 25, 2008 8:02 am

Re: handsFree - свободные клетки (для портала итд)

Сообщение Cooot »

Спасибо за плагин, думаю он может оказаться очень полезен.
Клетка выбирается одна из 8 смежных или и более дальние?
И что будет, если занято все ну прямо битком, как утром в трамвае?
И еще хотелось бы подробнее про вторую команду узнать. Что будет если просто написать:

Код: Выделить всё

do freer move ~
не используя до этого первую команду?
Изображение
Аватара пользователя
Святой Инквизитор
Грамотный
Сообщения: 455
Зарегистрирован: Вт окт 28, 2008 3:57 am
Сервер RO:: DarkRO
Откуда: Далёкая и тёмная страна Украина
Контактная информация:

Re: handsFree - свободные клетки (для портала итд)

Сообщение Святой Инквизитор »

Ух всё работает на отличненько автору ОГРОМНОЕ СПАСИБО!
Изображение Изображение
Настрою конфиг, напишу макрос - не дорого.
Стучать в асю (есть в профиле).
EternalHarvest
Разработчик
Сообщения: 819
Зарегистрирован: Пн окт 27, 2008 9:49 pm

Re: handsFree - свободные клетки (для портала итд)

Сообщение EternalHarvest »

kLabMouse писал(а)::)
Нихарашо делать кучу вложеных цыклов. Ибо любой язык програмирования, на любой платформе таким боком тормознёш по полной.
В курсе... Но всё работает и функция на практике вызывается нечасто.
Cooot писал(а):Клетка выбирается одна из 8 смежных или и более дальние?
По умолчанию - квадрат "радиусом" 7 клеток. Можно задать в конфиге параметром handsFree_spread.
Cooot писал(а):И что будет, если занято все ну прямо битком, как утром в трамвае?
Ничего не будет, только сообщение в консоль что всё занято.
Cooot писал(а):И еще хотелось бы подробнее про вторую команду узнать. Что будет если просто написать:

Код: Выделить всё

do freer move ~
не используя до этого первую команду?
Ничего полезного не будет. Первая команда - "генератор" координат. Вторая нужна при для их повторного использования (зайти в открытый портал, например).
Аватара пользователя
Святой Инквизитор
Грамотный
Сообщения: 455
Зарегистрирован: Вт окт 28, 2008 3:57 am
Сервер RO:: DarkRO
Откуда: Далёкая и тёмная страна Украина
Контактная информация:

Re: handsFree - свободные клетки (для портала итд)

Сообщение Святой Инквизитор »

Нашёл одну не доработку... оно не проверяет LOS к той точке из-за чего иногда скилы туда не достают. Возможно ли туда ка нибудь вмонтировать эту проверку?

Добавлено спустя 12 минут 42 секунды:
А вот вам и первая ошибка:

Код: Выделить всё

Stack trace:
Modification of non-creatable array value attempted, subscript -2 at K:/Downloads/??????/BOT (Yggdrasill berry) Priest/plugins/handsFree.pl line 34.
 at K:/Downloads/??????/BOT (Yggdrasill berry) Priest/plugins/handsFree.pl line 34
	handsFree::handsFreeAction() called at K:/Downloads/??????/BOT (Yggdrasill berry) Priest/plugins/handsFree.pl line 84
	handsFree::handsFree('free', 'sl 79 ~ 10') called at src/Commands.pm line 252
	Commands::run('free sl 79 ~ 10') called at plugins/Macro/Utilities.pm line 316
	Macro::Utilities::processCmd('free sl 79 ~ 10') called at plugins/Macro/Utilities.pm line 347
	Macro::Utilities::callMacro() called at plugins/Macro/Automacro.pm line 482
	Macro::Automacro::automacroCheck('AI_pre', 'undef', 'undef') called at src/Plugins.pm line 440
	Plugins::callHook('AI_pre') called at src/AI/CoreLogic.pm line 112
	AI::CoreLogic::iterate() called at src/functions.pl line 593
	main::mainLoop_initialized() called at src/functions.pl line 70
	main::mainLoop() called at src/Interface.pm line 75
	Interface::mainLoop('Interface::Console::Win32=HASH(0x2272140)') called at openkore.pl line 96
	main::__start() called at start.pl line 119

Died at this line:
        for ($y = $char->{pos}{y}-$spread; $y <= $char->{pos}{y}+$spread; $y++) {
*          $count -= !($reach[$x][$y] = $field->isWalkable ($x, $y));
        }
Изображение Изображение
Настрою конфиг, напишу макрос - не дорого.
Стучать в асю (есть в профиле).
Ответить