Page 8 of 10

Re: Script.dll + include

Posted: 2013-06-18 18:37:18
by Incorrect User
Я так понял это значит на одном тайле земли сразу три тайла(бывает и больше) статики. Как это можно обыграть?

Re: Script.dll + include

Posted: 2013-06-18 18:41:30
by Juicy Fruit
Бинго!
Ну, я не просто так же писал это на 6 странице:

Code: Select all

sub Test()
   uo.setmulpath('E:\Ultima Online')
   var tileid = uo.getstatictiles(uo.getx(), uo.gety() + 1, 0)
   uo.print('tileid='+tileid)
   if tileid=='' then
      uo.print('Тут нет статики.')
      return
   endif
   dim tiles[20] #20 хватит думаю
   var l=Str2Tiles(tiles,tileid)
   var i,f
   if l>0 then
      for i=0 to l-1
         f=UO.GetTileFlags(1,tiles[i])
         uo.print('tile='+tiles[i])
         uo.print('flags='+f)
         if contains(uo.hex2int(f),0x40) then
            uo.print("Непроходимый тайл!")
         else
            uo.print("Проходимый тайл!")
         end if
      next
   endif
end sub

Sub Str2Tiles(a,s)
   var i,l=len(s),b='',ptr=0
   if not l then
      return 0
   endif
   for i=0 to l-1
      if s[i]<>',' then
         b=b+s[i]
      else
         a[ptr]=b
         b=''
         ptr=ptr+1
      endif
   next
   a[ptr]=b
   ptr=ptr+1
   return ptr
end sub

Если решил с Z координатой выводить - допили во 2 функцию ещё 1 массив для Z и разбор Z координат.

Re: Script.dll + include

Posted: 2013-06-18 18:53:41
by Incorrect User
Так он возвращает сразу на три тайла информацию а не на один. Я так понимаю, нужно проверять только один, самый последний в списке, так как он верхний?

Re: Script.dll + include

Posted: 2013-06-18 18:58:31
by Incorrect User
+ Нашел место, там куча тайлов, при нажатии теста вылетает уо с надписью Abnormal program termination

Re: Script.dll + include

Posted: 2013-06-18 19:06:15
by Juicy Fruit
Juicy Fruit wrote:GetLandscapeTile возвращает информацию в формате TileID, при включенной ShowZ в формате TileID(Z)
GetStaticTiles так же, как и GetLandscapeTile, но перечисляет все тайлы статики, находящиеся в заданных координатах через запятую. Если тайлов статики не обнаружено - вернет пустую строку.
При ошибке возвращают строку -1.

Читай описание внимательнее)
Дай координаты места.

Re: Script.dll + include

Posted: 2013-06-18 19:08:52
by Incorrect User
Скала в Cove 2231,1234,0

Re: Script.dll + include

Posted: 2013-06-18 19:27:54
by Juicy Fruit

Code: Select all

tileid=0x179B,0x179B,0x1799,0x1797,0x179C,0x1799,0x1799,0x17AD,0x1798,0x179C,0x179B,0x0CAF,0x17B2,0x0CAF,0x1797,0x1799,0x1798,0x179A,0x17A9,0x179B
tile=0x179B
flags=0x000000C1
Непроходимый тайл!
tile=0x179B
flags=0x000000C1
Непроходимый тайл!
tile=0x1799
flags=0x000000C1
Непроходимый тайл!
tile=0x1797
flags=0x000000C1
Непроходимый тайл!
tile=0x179C
flags=0x000000C1
Непроходимый тайл!
tile=0x1799
flags=0x000000C1
Непроходимый тайл!
tile=0x1799
flags=0x000000C1
Непроходимый тайл!
tile=0x17AD
flags=0x000000C1
Непроходимый тайл!
tile=0x1798
flags=0x000000C1
Непроходимый тайл!
tile=0x179C
flags=0x000000C1
Непроходимый тайл!
tile=0x179B
flags=0x000000C1
Непроходимый тайл!
tile=0x0CAF
flags=0x00000201
Проходимый тайл!
tile=0x17B2
flags=0x000000C1
Непроходимый тайл!
tile=0x0CAF
flags=0x00000201
Проходимый тайл!
tile=0x1797
flags=0x000000C1
Непроходимый тайл!
tile=0x1799
flags=0x000000C1
Непроходимый тайл!
tile=0x1798
flags=0x000000C1
Непроходимый тайл!
tile=0x179A
flags=0x040000C1
Непроходимый тайл!
tile=0x17A9
flags=0x000000C1
Непроходимый тайл!
tile=0x179B
flags=0x000000C1
Непроходимый тайл!

dim tiles[20] поставь побольше, там всего 20 тайлов. Значит, может быть и больше.
Ошибку не выдал.

Re: Script.dll + include

Posted: 2013-06-18 19:34:19
by Incorrect User
Поставил 50, не вылетает. Но скрипт скажет что прохода нет если хоть в одном тайле из всех есть флаг 0х40. Я стою в спиче, он выдает мне пачку непроходимых, значит скрипт в таких местах будет говорить что прохода нет.

Re: Script.dll + include

Posted: 2013-06-18 19:34:57
by Incorrect User
Запиливай в инжу ходилку из стелса :P

Re: Script.dll + include

Posted: 2013-06-18 19:43:39
by Juicy Fruit
У меня в модуле есть, но ооооочень долгая и корявая :DD
Если все тайлы смотреть - да, если отсеивать по Z координате - то можно избежать этого, сравнивать свою Z и +/-10Z тайла, к примеру.

Re: Script.dll + include

Posted: 2013-06-18 19:52:42
by Incorrect User
В общем как всегда, без костылей никуда. Буду ходить без проверки, для мининга не проблема, для ламбера... наверное тоже, так как еще сама по себе ходилка неадекватная а может это она так из за кривой проверки петляла. Щас затестирую как будет ходить, надеюсь не будет в лесу тайлов непроходимых там где свободное место.

Re: Script.dll + include

Posted: 2013-06-18 19:58:53
by Mirage
Скала в Cove 2231,1234,0

На родной карте там просто много кустов. Тайлы обычные - ни под ни над точкой ничего нет. Скала и проходимая земля рядом.

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

Re: Script.dll + include

Posted: 2013-06-18 20:23:20
by Incorrect User
Выложил ходилку с новой проверкой тут viewtopic.php?f=20&t=6742&p=94554#p94554 Проверяет столько тайлов перед собой, сколько нужно сделать шагов. Обход при этом петляет на пол км. Хотелось бы чтобы просто проверял три тайла наискосок в одну сторону и если и там нет прохода то 3 тайла в противоположную сторону.

Re: Script.dll + include

Posted: 2013-06-22 17:41:18
by Juicy Fruit
Слил всю инфу по доступным функциям в первый пост.

Переписал алгоритм поиска пути. Теперь он не колдует пол часа над файлами УО. Вычисление пути на фрагменте карты 150х150 (без учета игровых объектов) заняло около секунды. С учетом объектов УО - 3 секунды.
Описание класса:

Code: Select all

PathFind(UOPath, MapNum, Z, Alg) - Первый конструктор. UOPath - путь к папке УО с *.mul файлами, MapNum - номер карты, для которой вычисляется путь, Z координата (пока что не работает), Alg - Выбор алгоритма поиска пути, может принимать значения 0 (волновой алгоритм поиска) и 1 (алгоритм поиска А*) см. википедию по сути алгоритмов.
PathFind(UOPath, MapNum, Z, Alg, ScreenCatalog) - Второй конструктор. По первым 4 параметрам см. выше. ScreenCatalog - путь к папке, куда сохранять изображения с фрагментом карты, на котором ведется поиск пути. На картинке отражается цветом:
Белый - Свободные тайлы
Черный - Заблокированные тайлы
Синий - Вода
Темно-бардовый - Мост (тайлы статики, имеющие флаг 0x00000400 (Bridge))
Темно-синий - Точка, от куда ведется расчет пути
Фиолетовый - Точка, куда ведет путь
Setup(PX, PY, TX, TY) - Устанавливает начальную и конечную точки и извлекает по ним путь.
PX PY - координаты начальной точки пути.
TX TY - координаты конечной точки пути.
First() - Доступ к первому элементу массива.
Last() - Доступ к последнему элементу массива.
SetPos(Position) - Изменить текущий указатель позиции в массиве на Position. Индексы от 0 до Size()-1
GetPos() - Получить текущий указатель на позицию в массиве.
GetX() - Получить координату Х текущий позиции.
GetY() - Получить координату Y текущий позиции.
Next() - Доступ в следующему элементу массива. Вернёт 1 если удачно. 0 если это конец массива.
Back() - Доступ в предъидущему элементу массива. Вернёт 1 если удачно. 0 если это начало массива.
Size() - Вернёт размер массива.
Clear() - Очистит массив с картой и вектор пути.
AddObj(Graphic, X, Y) - Добавит в класс игровой объект с типом Graphic (строка) в координатах X и Y (числа)


Работает с файлами: map*.mul, statics*.mul, staidx*.mul, tiledata.mul, multi.mul, art.mul, artidx.mul, verdata.mul
Карта, созданная классом:
Image

Пример кода поиска пути:

Code: Select all

var UOPath='E:\Ultima Online Abyss' #Путь к папке с *.mul файлами УО
var ScreenPath='E:\UOPathScreens' #Путь к папке, куда сохранять скрины поиска пути
var PathAlg=1 #Индекс алгоритма
var PathMap=0 #Индекс карты
var CheckUOObject=1 #Учитывать игровые объекты при поиске пути? 0 - нет; 1 - да

Sub abs(i)
   if i<0 then
      i=i*(-1)
   endif
   return i
end sub

sub tWalk1()
   var i,gr=''
   var mapout=PathFind(UOPath,PathMap,uo.getz(),PathAlg,ScreenPath)
   var x=uo.getx() #От куда начинаем путь по X
   var y=uo.gety() #От куда начинаем путь по Y
   var ChestX=1773 #Куда идем по X
   var ChestY=3096 #Куда идем по Y
   if CheckUOObject then
      var dx=abs(x-ChestX)
      var dy=abs(y-ChestY)
      if dx<dy then #Получим наибольшее значение дистанции до объекта
         dx=dy
      endif
      if remain(dx,2) then #Если есть остаток от деления на 2, то прибавим 1
         dx=dx+1
      endif
      dx=dx*2 #Максимальная дистанция поиска объектов для алгоритма = максимальная дистанция * 2
      uo.set('finddistance',str(dx))
      uo.findtype(-1,-1,'ground')
      uo.ignorereset()
      if uo.findcount() then #Поиск предметов на земле, пока не кончатся
         repeat
            gr=uo.getgraphic('finditem')
            #Проверка на людей. Все живые объекты нужно исключить из списка. Проверка Z координаты, если не больше 10 то заносим в список
            if gr<>'0x0190' and gr<>'0x0191' and abs(uo.getz('finditem')-uo.getz('self'))<10 then
               mapout.addobj(gr,uo.getx('finditem'),uo.gety('finditem'))
            endif
            uo.ignore('finditem')
            uo.findtype(-1,-1,'ground')
         until not uo.findcount()
      endif
      uo.ignorereset()
   endif
   uo.print('Setup...')
   mapout.Setup(x,y,ChestX,ChestY) #Запускаем алгоритм поиска
   if mapout.Size() then #Если есть размер вектора пути - алгоритм успешно нашел путь
      uo.print('Путь вычислен!')
      mapout.first() #Ставим указатель на первый элемент массива
      repeat
         #Тут делаем коррекцию ходьбы.
         uo.print('X='+str(mapout.getx())+' Y='+str(mapout.gety()))
         wait(10)
      until not mapout.next() #Крутим цикл, пока массив не дойдет до конца
      #Тут производим какие-то действия, добираем ресы из сундука или ресаемся...
      mapout.last() #Устанавливаем указатель на последний элемент массива (он уже там, но малоли...)
      repeat
         #Тут делаем коррекцию ходьбы.
         uo.print('X='+str(mapout.getx())+' Y='+str(mapout.gety()))
         wait(10)
      until not mapout.back() #Крутим цикл до начала вектора
   else #Если нет размера вектора пути - путь не найден. Можно попробовать создать поиск с другим алгоритмом.
      uo.print('Ошибка вычисления пути!')
   endif
end sub

Может застрять на входах/выходах из пещер, там сложная статика, пока ещё не разобрался с ней. Клиент не может пройти на свободном месте.

Re: Script.dll + include

Posted: 2013-06-22 18:10:36
by Incorrect User
А саму функцию движения приделаешь?

Re: Script.dll + include

Posted: 2013-06-22 18:26:33
by Juicy Fruit
За функцию движения можно взять твою ходилку (модифицированную Беяндера), только без проверок на тайл и т.п. От нее нужно по сути только изменение направления чара и сделать шаг.
В модуль нет смысла "вшивать" ходилку. Он не умеет определять координаты, направление чара и т.п.

Re: Script.dll + include

Posted: 2013-06-22 18:55:55
by Incorrect User
Тогда нужно будет поковырять её. Даже делать для этой твоей определялки просто новый кусок, там много лишнего, нужно под эту сделать свою. Ты мне обьясни как чар будет получать координаты в какую сторону идти? Путь он определил, ну а куда шагать, чтобы шел именно по тем тайлам которым нужно. Я так понимаю долженб быть список точек на каждом изменении направления, когда чар поворачивает в любое из 8 направлений нужно знать точку этого места. В итоге будем просто жать на нужную кнопку пока чар не дойдет до нужных координат, потом жмем другую кнопку и т.д.

Re: Script.dll + include

Posted: 2013-06-22 18:59:16
by Juicy Fruit

Code: Select all

      mapout.first() #Ставим указатель на первый элемент массива
      repeat
         walker(mapout.getx(),mapout.gety(),1) #Ходилка на нужный тайл
      until not mapout.next() #Крутим цикл, пока массив не дойдет до конца
Если так понятнее будет.

Re: Script.dll + include

Posted: 2013-06-22 19:14:01
by Incorrect User
Понял, к ней нужно допилить просто кусок с ходьбой, весь валкер не нужен, там обход дэбильный, будем считать что препятствий на пути нет. Сделаю когда освобожусь, выложу сдесь.

Re: Script.dll + include

Posted: 2013-06-22 21:53:27
by Incorrect User
ScreenPath='E:\UOPathScreens' #Путь к папке, куда сохранять скрины поиска пути

Это обязательно? и как отключить если что.