Yoko
http://forum.yoko.com.ua/

autoLumber - вырубка с автопоиском деревий
http://forum.yoko.com.ua/viewtopic.php?f=15&t=12382
Page 1 of 8

Author:  Destruction [ 2007-08-29 23:35:52 ]
Post subject:  autoLumber - вырубка с автопоиском деревий

Давно не проскакивало хороших скриптов с автопоиском деревий, а ведь это неплохой по-сути дела скрипт получается..

Я собственно говоря набросал вкратце:
Code:
#Lumbjacking с автопоиском деревий (c) Destruction, v1.0
var hatchet = "0x0F43"
Sub searchTree()
   var i, x, y, t, stp, max_search = 24 ; максимальная дистанция для генерации координат.
   var cx = uo.getX()
   var cy = uo.getY()
   for i = 1 to max_search
      for x =-i to i
         stp = 1
         if not i == abs( x ) then
            stp = abs( i ) * 2
         endif
         for y = -i to i step stp
            if NOT uo.getGlobal( 't:' + str( x + cx ) + "," + str( y + cy ) ) == "empty" then
               t = IsTreeTile( x + cx, y + cy )
               if not t == false then
                  uo.setGlobal( "tree_x", str( x + cx ) )
                  uo.setGlobal( "tree_y", str( y + cy ) )
                  uo.setGlobal( "tree_t", str( t ) )
                  return false
               else
                  uo.setGlobal( 't:' + str( x + cx ) + "," + str( y + cy ), 'empty' )
               endif
            endif
         next
      next
   next
   uo.print( "Found no tree, exit." )
   uo.exec( "terminate autoLumber" )
   return false
endsub

sub autoLumber()
   searchTree()
   doMineTree()
endsub

Sub doMineTree()
   var x, y, t
   var end = "appears immune|nothing here|reach this"
   var try = "You put|fail"
   repeat
      x = val( uo.getGlobal( "tree_x" ) )
      y = val( uo.getGlobal( "tree_y" ) )
      t = val( uo.getGlobal( "tree_t" ) )
      uo.setGlobal( 't:' + str( x ) + "," + str( y ), "empty" )
      Walker( x, y, 1 )
      uo.exec( "exec searchTree" )
      repeat
         if uo.waiting() then
            uo.canceltarget()
         endif
         deljournal( try + "|" + end )
         uo.waittargettile( str( t ), str( x ), str( y ), str( uo.getZ() ) )
         uo.usetype( hatchet )
         repeat
            wait( 100 )
         until uo.injournal( try + "|" + end )
      until uo.injournal( end )
      while uo.getGlobal( "tree_x" ) == str( x ) && uo.getGlobal( "tree_y" ) == str( y )
         wait( 100 )
      wend
   until false
endsub

Sub deljournal( msg )
   while uo.injournal( msg )
      uo.setjournalline( uo.injournal( msg ) -1, '' )
   wend
endsub

Sub IsTreeTile( x, y )
   var i, tree_count = 20
   DIM tree[ val( str( tree_count ) ) ]
   tree[0] = 3274
   tree[1] = 3275
   tree[2] = 3276
   tree[3] = 3277
   tree[4] = 3280
   tree[5] = 3283
   tree[6] = 3286
   tree[7] = 3289
   tree[8] = 3291
   tree[9] = 3292
   tree[10] = 3294
   tree[11] = 3295
   tree[12] = 3296
   tree[13] = 3299
   tree[14] = 3302
   tree[15] = 3394
   tree[16] = 3395
   tree[17] = 3417
   tree[18] = 3440
   tree[19] = 3461
   for i = 0 to tree_count -1
      if uo.privategettile( x, y, -1, tree[i], tree[i] ) then
         return tree[i]
      endif
   next
   return false
endsub


Для работы скрипта потребуется ходилка вида Walker( x, y, prec ), я использовал ходилку (c) Beyonder.

Собственно это лишь набросок, если сюда прикрутить пару-тройку рун, то получится может весьма симпатичная штука... Ну или можно прикрутить авторазметку массива для другого скрипта, который больше нравится :roll:

Описания нету, не писал..

У скрипта есть один минус перед скриптами с разметкой - я не придумал как корректно определить z-координату дерева, поэтому она не всегда верная получается, что не совсем порядочно.. Вернее определить её можно, но только после попытки вырубки.. вообще надо будет подумать..


Вкратце о работе скрипта: после запуска основной ф-ции autoLumber - скрипт начинает искать дерево в радиусе 24 тайлов (если его там не будет - будет весьма нехорошо...), найдя дерево - запускается ф-ция вырубки дерева, которая в первую очередь запускает процесс поиска следущего дерева в отдельном потоке и отправляется к дереву, подойдя к дереву - функция его вырубает до предела, если нужно - ждёт пока не будет найдено следущее дерево, как только следущее дерево найдено - функция вырубки начинается сначала.
PS: Т.к. это только набросок, то не найдя дерева - скрипт зациклится.. Вобщем дописывать под свои нужды :)

Ходилка (с) Beyonder - viewtopic.php?p=66813#66813

Author:  Grin [ 2007-08-30 01:36:53 ]
Post subject: 

если большое желание искать деревья в отдельном потоке, то было бы интересней если этот поток существовал всегда, и искал бы дерево по команде другого потока, это уменьшит кол-во глобальных переменых и постояные запуски новых тредов.

замечено что uo.privategettile может давольнотаки быстро похоронить оперативку. По этому искать деревья есть смысл в диапозонах, но это если неважен тип дерева.

Кооржината Z можно получить лишь подбором (не удачные попытки и тд), ну или используем асм или перл;)

Author:  Destruction [ 2007-08-30 13:20:18 ]
Post subject: 

Ну, если ты внимательно посмотришь на то, как оно реализовано, то найдёшь башой минус в "аглоритме" поиска деревий..

Начав искать на дистанции 2, он так же обыщет на дистанции 1, что уже делал ранее.. Я незнаю, как правильно это реализовать..

Касательно постоянного поиска деревий - не совсем понял..

uo.asmMapGetZ не даёт нужную Z-координату, перл использовать не буду.

Задумавшись о других ошибках в алгоритме, я пришёл к выводу, что когда я запускаю искать дерево в новом потоке - он ищет относительно своих координат, а лучше было бы искать относительно координат дерева..

В любом случае, если надо быстро нарубить логов на стрелы - скрипт сработает на ура :)

Касательно привейтгеттайл - можно в целях экономии оперативки записать результат его работы в реестр, чем захламить реестр, но зато отличное кэширование результатов работы.. :)

Author:  Grin [ 2007-08-30 13:50:03 ]
Post subject: 

Quote:
Ну, если ты внимательно посмотришь на то, как оно реализовано, то найдёшь башой минус в "аглоритме" поиска деревий..

Начав искать на дистанции 2, он так же обыщет на дистанции 1, что уже делал ранее.. Я незнаю, как правильно это реализовать..

Касательно постоянного поиска деревий - не совсем понял..


Как раз для этого мы и оставляем поток поиска деревьев не тронутым, после нахождения дерева уходит в цикл по проверке глобальной переменной на ее изменение, извенилась ищим еще дерево, поиск можно о сущевствлять разными с пособами;)
тот же поиск по квадрату.

Quote:
uo.asmMapGetZ не даёт нужную Z-координату, перл использовать не буду.


а за чем тебе коррдинату получать?
UO.asmWaitTargetMapTile(string LogicType, number X, number Y, number Map)
UO.asmWaitTargetStaticTile(string LogicType, number X, number Y, number Map)
ты тут Z видишь?;)

Quote:
Касательно привейтгеттайл - можно в целях экономии оперативки записать результат его работы в реестр, чем захламить реестр, но зато отличное кэширование результатов работы.. :)


Память жрется инжектом, причем тут где хранить результат?
Поповоду памяти так не большое за мечание, это не говорит что от каманды надо о тказатся.

Author:  Destruction [ 2007-08-30 14:11:06 ]
Post subject: 

Касательно реестра - ты не понял, фишка в том, что он хранит данные даже после перезапуска уо :)

Я предлагаю после проверки привейтгеттайлом - записывать в реестр результат проверки, чем самым исключить проверку одного тайла дважды.. Один раз сожрёт память и больше не будет.. но хлам в реестре - тоже не круто :)

Касательно поиска деревий - до сих пор не понял, измени ф-цию плз, чтобы нормально работало :roll: Вернее смысл понял, как реализовать знаю, а вот, чтобы при этом начало нормально искать деревья (не проверяя тайл 0:0 - 24 раза, например..) - хз :roll:

Author:  Grin [ 2007-08-30 14:53:23 ]
Post subject: 

Code:
sub Init()

   uo.SetGlobal("Searched", "no")
   uo.SetGlobal("Searching", "yes")
   uo.exec("exec TreeSearch")
   wait(1000)
   uo.exec("exec Lamb")
   
end sub

sub TreeSearch()

   var mx, my, x, y
   var distance = 24
   
   for x = mx to mx+distance
      for y = my to my+distance
         if uo.privategettile(x, y, -1, 3274, 3302) then
         
            uo.SetGlobal("treeX", str(x))
            uo.SetGlobal("treeY", str(y))
            uo.SetGlobal("Searched", "yes")
            
            while uo.GetGloba("Searching") == "no"
               wait(200)
            wend
            
            uo.SetGlobal("Searched", "no")
            uo.SetGlobal("Searching", "no")
         endif
      next
   next
   uo.SetGlobal("Searched", "end")
   
end sub

sub Lamb()

   var treeX, treeY
   var result = uo.GetGlobal("Searched")
   
   while result <> "end"
      if result == "yes" then
      
         treeX = val(uo.GetGlobal("treeX"))
         treeY = val(uo.GetGlobal("treeY"))
         uo.SetGlobal("Searching", "yes")
         Walker( treeX, treeY, 1 )
         
         *рубим*
      endif
      result = uo.GetGlobal("Searched")
      wait(100)
   wend
   
end sub


смысл стал ясней?;)

Author:  Destruction [ 2007-08-30 15:30:52 ]
Post subject: 

Ясней, будем думать, пасип :)

А оно не будет пытаться рубить деревья, которые рубило пару минут назад?)

Author:  Grin [ 2007-08-30 16:08:49 ]
Post subject: 

нет конечно...
пока квадрат 24х24 не будет вырублен деревья не повторятся

Author:  Destruction [ 2007-08-30 23:48:32 ]
Post subject: 

Grin wrote:
нет конечно...
пока квадрат 24х24 не будет вырублен деревья не повторятся

Не вариант.. Где я играю (да и ещё много где), респ дерева около 10 часов, а квадрат 24х24 вырубается за 10 минут..

Author:  Grin [ 2007-08-31 23:54:31 ]
Post subject: 

Так я ж тебе не вариант обхода деревьев предлогал;)

А если думать об обходе то обход должен быть в границах прямоугольника (квадрат), и обход должен проходить змейкой...
причем змея должна быть с логикой;)

тоесть не во всех полосах могт быть деревья... ва в некоторых они слишком далеко что бы идти за ними и там всего 1 будет допустим...
ну тд..

Author:  Edred [ 2007-09-01 11:14:43 ]
Post subject: 

Во многих моих ламберах и минингах был реализован автопоиск деревьев/тайлов. Опыт есть. И сразу даю совет: найденное запоминать, запоминать позицию чара, при повторном приходе в эту позицию - автопоиск на фиг, использовать ранее запомненное. Так быстрее на порядок.

Author:  Grin [ 2007-09-01 13:03:49 ]
Post subject: 

при данном исполнении время на поиск невелируется проходом к дереву и его рубкой.
Собственно при паралельном потоке поиска задержек между деревьями не будет, да и не будет ее даже если искать в томже потоке... Скорость обработки выше да и деревья относительно рядом

ПС А вообе это из облости эксперементального скриптинга;) делать не фиг вот и страдаем;)

Author:  Edred [ 2007-09-01 21:17:03 ]
Post subject: 

Если не фиг делать - сделай то, что собирался. Я про библиотеку для стелса. Помнишь?

Author:  Grin [ 2007-09-02 04:27:07 ]
Post subject: 

Конечно помню.

Там было как минимум 2 проблемы, библиотека грузилась и выгружалась после отрабатывания скрипта который ее вызвал (или после за вершения последнего вызываюшего). Сие гдето не страшно, гдето можно обойти... но конкретное решение, надо знать чего юзеры хотят.

И ввторая трабла но то чно не вкурсе, скрипт паскаль както уж очень туго с укаателями работает. Через тип еще вродиб как то понимает, а получить или обратится по указателю вечно ругань;)

СМобственно безделие на форуме приводит к эксперементальныму скриптингу тут, но в реале дела по другому обстоят

Author:  Destruction [ 2007-09-02 15:23:29 ]
Post subject: 

Edred wrote:
Во многих моих ламберах и минингах был реализован автопоиск деревьев/тайлов. Опыт есть. И сразу даю совет: найденное запоминать, запоминать позицию чара, при повторном приходе в эту позицию - автопоиск на фиг, использовать ранее запомненное. Так быстрее на порядок.

Я про это кажется говорил парой сообщений выше..

Спрашиваю я как-раз таки про другое, у меня сейчас работает примерно так:
Code:
var max_distance = 24
for i = 1 to max_distance
    uo.set( 'finddistance', str( i ) )
    uo.findtype( 'tree', '-1', 'ground' )
    ; ...
next


Вот если внимательно подумать - такая конструкция, рашсиряя каждую итерацию границу на 1 клетку - каждый раз обыскивает ряд клеток, которые были только, что обысканы! Безусловно запоминание результатов проверки каждой клетки - напорядок ускорит дело (лично я проблем со скоростью не имею, пока рублю дерево - он ищет новое, всё успевает), тем не менее хотелось бы начать с исправления данного недостатка, а там глядишь и научимся запоминать вырубленные деревья (не проблема), а потом ещё и забывать таковые (уже несколько интереснее).

Author:  Grin [ 2007-09-02 15:35:54 ]
Post subject: 

ну вот... то про статику, то про динамику...

Уже была когждато от тебя идея похожая, но интерпретирую юю сейчас по другому... Берешь ишешь все делевья в ограниченом квадрате (не большом), записываешь в масив, рубишь по этому масиву двигаешься в торону следующегго квадрата и тд...

Кстати в перловом модуле есть функуия для работы с тайлами в указаной точке, на выходе список тайлов с сейрийниками если динамика, коринатой Z ну и с типом... ни каких вповторений ячеек сней нет;)

Author:  Edred [ 2007-09-02 20:39:22 ]
Post subject: 

Destruction wrote:
Code:
var max_distance = 24
for i = 1 to max_distance
    uo.set( 'finddistance', str( i ) )
    uo.findtype( 'tree', '-1', 'ground' )
    ; ...
next

Вот если внимательно подумать - такая конструкция, рашсиряя каждую итерацию границу на 1 клетку - каждый раз обыскивает ряд клеток, которые были только, что обысканы!


Неправильное понимание ситуации. Команда uo.findtype ничего ни в каких клетках не ищет. Она смотрит в памяти инжекта, к некоей табличке запомненных объектов, про которых пришла инфа в пакетах. Табличка индексирована, поэтому поиск фактически мгновенный. Найденный объект проверяется на соотвествие условиям поиска и либо отбрасывается, либо принимается за результат. Наиболее удобно на подобное посмотреть в стелсе - там эта табличка выводится на закладке worlds.

Я, конечно, первый раз слышу про поиск деревьев через findtype, у вас на шарде, что, деревья в мире ГМы лочат, что ли? Если деревья на карте - findtype их найти не может по определению.

Author:  Destruction [ 2007-09-03 18:34:11 ]
Post subject: 

Я привёл это как пример.. Деревья понятное дело оно не ищет, смотри первый скрипт - там ищет.

Вообще грин хорошую идею подал - запоминать найденные деревья, тогда всё будет ок.. :)

Вообще немного не так хотелось бы.. Кстате, Edred, если особо не вникать в то, что я пишу - как найти ближайшее дерево?

Author:  Edred [ 2007-09-03 21:25:56 ]
Post subject: 

Destruction wrote:
Кстате, Edred, если особо не вникать в то, что я пишу - как найти ближайшее дерево?


Перебором всех найденных деревьев.

Author:  Destruction [ 2007-09-10 22:33:48 ]
Post subject: 

Edred, вариант с перебором всех найденных деревий - собственно говоря не совсем вариант, т.к. мне нужно НАЙТИ ближайшее дерево, для этого нужно циклично, начиная с координат персонажа (вернее с соседних, но можно и свои проверить, хотя и нежелательно) проверять тайлы дерево / не дерево.

Проблема как раз-таки заключалаись в написании цикла, который будет проверять координаты по-порядку.

Собственно говоря - я не просто так апаю, после некоторого анализа данных которые необходимо получить, я написал такой цикл:
Code:
sub main()
var i, x, y, stp, max_search = 3 ; максимальная дистанция для генерации координат.
uo.textclear()
for i = 1 to max_search
   uo.textprint( "Group #" + str( i ) )
   for x =-i to i
      stp = 1
      if not i == abs( x ) then
         stp = abs( i ) * 2
      endif
      for y = -i to i step stp
         uo.textprint( str( x ) + " : " + str( y ) )
      next
   next
next
uo.textopen()
endsub


Разница вся в том, что этот цикл пусть и делает то же, что и первый, но этот - не выводит одинаковые координаты, т.е. так оптимальнее, что собственно говоря я и просил помочь мне достичь.

Page 1 of 8 All times are UTC+02:00
Powered by phpBB® Forum Software © phpBB Limited
https://www.phpbb.com/