Сверхточная ходилка (c) Beyonder

Anything and all.

Moderators: Murderator+, Murderator

dubd
Posts: 249
Joined: 2012-07-27 23:43:14

Re: Сверхточная ходилка (c) Beyonder

Post by dubd »

подскажите пожалуйста, как сделать так, чтобы скрипт к которому ты привязываешь эту ходилку рапознавал её и ходил?
Incorrect User
Posts: 949
Joined: 2011-05-23 00:33:30

Re: Сверхточная ходилка (c) Beyonder

Post by Incorrect User »

Иногда чар делает один круг по пути от дерева до дерева, причем препятствий по пути нет никаких, может быть несколько раз за ходку, как убрать? Может что с настройками? Мои настройки

Code: Select all

var MaxTraceDistance=5
var TraceLoopIncrease=5#Увеличение MaxTraceDistance при исчерпании количества ходов
var LimitTrace=15#Сколько шагов в ОБЕ стороны от начальной точки обхода прекращают ходилку (выхода нет).
var Speed=3
var StepTimeOut=600#Таймаут шага. Устанавливать не в размер пинга, а в размер шага + размер пинга.
# Для ходьбы - 500 + Ping
# Для бега/ходьбы на лошади - 300 + Ping
# Бег на лошади - 150 + Ping
var CheckCnt=1 #Количество слепых проверок. УВЕЛИЧИВАЕТ В СТОЛЬКО РАЗ ТАЙМАУТ. Использовать только на БЫСТРОМ но НЕСТАБИЛЬНОМ коннекте. При большом пинге будет УЖАС.
var DynamicPause=10 #Минимальные паузы в циклах. Чем меньше число - тем меньше рывков и тем больше нагрузка процессора.
var CheckCnt=1 #Количество слепых проверок. УВЕЛИЧИВАЕТ В СТОЛЬКО РАЗ ТАЙМАУТ. Использовать только на БЫСТРОМ но НЕСТАБИЛЬНОМ коннекте. При большом пинге будет УЖАС.
var DynamicPause=10 #Минимальные паузы в циклах. Чем меньше число - тем меньше рывков и тем больше нагрузка процессора.
Incorrect User
Posts: 949
Joined: 2011-05-23 00:33:30

Re: Сверхточная ходилка (c) Beyonder

Post by Incorrect User »

Если установить в

Code: Select all

var CheckCnt=1 #Количество слепых проверок. УВЕЛИЧИВАЕТ В СТОЛЬКО РАЗ ТАЙМАУТ. Использовать только на БЫСТРОМ но НЕСТАБИЛЬНОМ коннекте. При большом пинге будет УЖАС.
значение 2 то после через некоторое время рубки вылетает парсер. Инжект 505.18 гамп фикс.
Incorrect User
Posts: 949
Joined: 2011-05-23 00:33:30

Re: Сверхточная ходилка (c) Beyonder

Post by Incorrect User »

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

Code: Select all

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; var Prec=3 # Как близко следует подойти к цели (Precision)
; В функции IsPass, содержиться список проходимых тайлов.
; Walker(X, Y, Prec) - идем к цели с координатами X, Y. Возвращает 1 в случае успешного достижения цели, и 0 - при невозможном обходе (путь не найден)
; Tracer(StartDir, Direction) - трассировка 1 шага. Возвращает направление по которому получилось сдвинуться с места. StartDir # -  направление последнего движения, Direction ( - 1 или  + 1) направление обхода.  - 1 - по часовой стрелке,  + 1 против часовой #стрелки. Направления скрипт использует личного формата:
; 1 - влево вниз
; 2 - вниз
; 3 - вправо вниз
; 4 - вправо
; 5 - вправо вверх
; 6 - вверх
; 7 - влево вверх
; 8 - влево
; Tracer(StartDir, Direction) - идеально подходит для рыбалки вдоль берега так как она будет обходить берег бесконечно (1 #запуск функции = 1 шаг обхода).
var MaxTraceDistance=4 ; Максимальная длина обхода. Желательно ставить с расчета возможных препятсвий. Если ставить очень #большие числа, кодилка может пойти в обход пол мира чтобы дойти к соседнему дереву.
var TraceLoopIncrease=4 ; Увеличение MaxTraceDistance при исчерпании количества ходов.
var LimitTrace=12 ; Сколько шагов в обе стороны от начальной точки обхода прекращают ходилку (выхода нет).
var Speed=3 ; Сколько шагов делать за раз между проверками.
var DynamicPause = 10 ; Минимальные паузы в циклах. Чем меньше число - тем меньше рывков и тем больше нагрузка процессора.
var steptimer = 2 ; Таймер на шаг(Значение 1 = 100мс). Время за которое чар проходит 1 тайл, если за это время чар не сдвинется с места скрипт расценит это как препятствие и начнет обходить.
sub Walker(GoX, GoY, Prec)
  uo.setglobal("BlindWalk", "0") ; не использовать проверку тайлов, а использовать ходьбу наощупь. 0 - проверяем тайлы, 1 - не проверяем.
  var LastDir
  var MoveRes
  var TracerCnt
  uo.setglobal("GlobalGoX", str(GoX))
  uo.setglobal("GlobalGoY", str(GoY))
  while not IsEnd(GoX, GoY, Prec)
    TracerCnt = MaxTraceDistance
    repeat
      LastDir=GoUntilHit(GoX, GoY, Prec)
      if IsEnd(GoX, GoY, Prec) then
        return 1
      end if
      MoveRes = FullAroundTrace(LastDir, GoX, GoY, Prec, TracerCnt)
      if TracerCnt > LimitTrace then
        return 0
      endif
      TracerCnt = TracerCnt + TraceLoopIncrease
    until MoveRes == 1
  wend
  return 1
end sub

Sub FullAroundTrace(StartDir, GoX, GoY, Prec, MaxTrace)
  var LineX=UO.GetX()
  var LineY=UO.GetY()
  var CurDir=StartDir
  var Direction=CountDirection(GoX, GoY, CurDir, Prec)
  var StartX, StartY
  var MovesDone=0
  repeat
    StartX=UO.GetX()
    StartY=UO.GetY()
    CurDir=Tracer(CurDir, Direction, Prec)
    if (CurDir==GetDir(GoX, GoY, Prec)) then
      return 1
    endif
    if MovesDone>0 and PrevMoveCross(GetDirToDir(UO.GetDir(), Prec), LineX, LineY, GoX, GoY, StartX, StartY, Prec) then
      return 1
    end if
    MovesDone=MovesDone + 1
    CurDir=AddToDir(CurDir,  - Direction, Prec)
  until MovesDone>MaxTrace
  return 0
end sub

Sub CountDirection(GoX, GoY, StartDir, Prec)
  var GoDir=GetDir(GoX, GoY, Prec)
  var MyX=UO.GetX()
  var MyY=UO.GetY()
  if GoDir<StartDir then
    return  - 1
  end if
  if GoDir>StartDir then
    return 1
  end if
  if Abs(MyX - GoX)>Abs(MyY - GoY) then
    if (GoDir==3) or (GoDir==7) then
      return  - 1
    else
      return 1
    end if
  else
    if (GoDir==1) or (GoDir==5) then
      return  - 1
    else
      return 1
    end if
  end if
end sub

Sub PrevMoveCross(Dir, x1, y1, x2, y2, StartX, StartY, Prec)
  var x3, y3, x4, y4
  x3=StartX
  y3=StartY
  x4=StartX + (XFromDir(Dir) - StartX)*Speed
  y4=StartY + (YFromDir(Dir) - StartY)*Speed
  return LinesCrossing(x1, y1, x2, y2, x3, y3, x4, y4, Prec)
end sub

Sub LinesCrossing(x1, y1, x2, y2, x3, y3, x4, y4, Prec)
  if x1==x3 and y1==y3 then
    return false
  end if
 
  var ua1=(x4 - x3)*(y1 - y3) - (y4 - y3)*(x1 - x3)
  var ub1=(y4 - y3)*(x2 - x1) - (x4 - x3)*(y2 - y1)
 
  var ua2=(x2 - x1)*(y1 - y3) - (y2 - y1)*(x1 - x3)
  var ub2=(y4 - y3)*(x2 - x1) - (x4 - x3)*(y2 - y1)
 
  #Check for parallel lines
  if (ub1 == 0) or (ub2 == 0) then
    return false
  end if
  var u1=ua1/ub1
  var u2=ua2/ub2
 
  if IsDiap(u1, 0, 1, 0.01) and IsDiap(u2, 0, 1, 0.01) then
    return true
  else
    return false
  end if
end sub

Sub IsDiap(X, X0, X1, Prec)
  if X<=X0 + Prec and X>=X1 - Prec OR X>=X0 - Prec and X<=X1 + Prec then
    return true
  end if
  return false
end sub

Sub GoUntilHit(GoX, GoY, Prec)
  var LastDir
  LastDir=GetDir(GoX, GoY, Prec)
  var CouldMove
  repeat
    LastDir=GetDir(GoX, GoY, Prec)
    if LastDir<>0 and not IsEnd(GoX, GoY, Prec) then
      CouldMove=TryDir(LastDir, Prec)
    end if
  until LastDir==0 or IsEnd(GoX, GoY, Prec) or not CouldMove
  return LastDir
end sub

Sub IsEnd(GoX, GoY, Prec)
  if Abs(UO.GetX() - GoX)<=Prec and Abs(UO.GetY() - GoY)<=Prec then
    return true
  else
    return false
  end if
end sub

Sub GetDir(GoX, GoY, Prec)
  var MyX=UO.GetX()
  var MyY=UO.GetY()
  var DiffX=Abs(UO.GetX() - GoX)
  var DiffY=Abs(UO.GetY() - GoY)
  var GoDir=0
  if (DiffX/(DiffY + 0.1))>=2 then
    if (MyX>GoX) then
      GoDir=7
    else
      GoDir=3
    end if
  else
    if (DiffY/(DiffX + 0.1))>=2 then
      if (MyY>GoY) then
        GoDir=5
      else
        GoDir=1
      end if
    else
      if (MyX>GoX) and (MyY>GoY) then
        GoDir=6
      else
        if (MyX>GoX) and (MyY<GoY) then
          GoDir=8
        else
          if (MyX<GoX) and (MyY>GoY) then
            GoDir=4
          else
            if (MyX<GoX) and (MyY<GoY) then
              GoDir=2
            end if
          end if
        end if
      end if
    end if
  end if
  return GoDir
end sub

Sub Tracer(StartDir, Direction, Prec)
  var CurDir=StartDir
  var Result
  repeat
    Result=TryDir(CurDir, Prec)
    if not Result then
      CurDir=AddToDir(CurDir, Direction, Prec)
    end if
  until Result
  return Result
end sub

Sub AddToDir(Dir, Cnt, Prec)
  var NewDir=Dir
  NewDir=NewDir + Cnt
  while NewDir>8
    NewDir=NewDir - 8
  wend
  while NewDir<1
    NewDir=NewDir + 8
  wend
  return NewDir
end sub

Sub TryDir(Dir, Prec)
  var BegX=UO.GetX(), BegY=UO.GetY(), GoX=BegX, GoY=BegY
  GoX=XFromDir(Dir)
  GoY=YFromDir(Dir)
  if not IsPass(GoX, GoY) then
    return false
  end if
  return TurnAndGoDir(Dir, Prec)
end sub

Sub XFromDir(Dir)
  if Dir==2 OR Dir==3 Or Dir==4 then
    return (UO.GetX() + 1)
  end if
  if Dir==6 OR Dir==7 Or Dir==8 then
    return (UO.GetX() - 1)
  end if
  return (UO.GetX())
end sub

Sub YFromDir(Dir)
  if Dir==8 OR Dir==1 Or Dir==2 then
    return (UO.GetY() + 1)
  end if
  if Dir==4 OR Dir==5 Or Dir==6 then
    return (UO.GetY() - 1)
  end if
  return (UO.GetY())
end sub

Sub TurnAndGoDir(Dir, Prec)
  var StartDir=GetDirToDir(UO.GetDir(), Prec), StartX=UO.GetX(), StartY=UO.GetY(), EndDir, timer
  #Start Primary test
  if GoDir(Dir, Prec) then
      return Dir
  else
      return 0
  end if
end sub

Sub GetDirToDir(GotDir, Prec)
  var ChangedDir = - GotDir
  ChangedDir = AddToDir(ChangedDir, 5, Prec)
  return ChangedDir
end sub

Sub GoDir(Dir, Prec)
  var circle, StartDir=GetDirToDir(UO.GetDir(), Prec), StartX=UO.GetX(), StartY=UO.GetY(), EndDir, timer
  dim Dirs[9]
  Dirs[1]=35
  Dirs[2]=40
  Dirs[3]=34
  Dirs[4]=39
  Dirs[5]=33
  Dirs[6]=38
  Dirs[7]=36
  Dirs[8]=37
   var DistanceX=Abs(UO.GetX()-val(UO.GetGlobal("GlobalGoX")))
   var DistanceY=Abs(UO.GetY()-val(UO.GetGlobal("GlobalGoY")))
  var GoDistance
  if (DistanceX - Prec) < Speed and (DistanceX - Prec) > (DistanceY - Prec) then
    GoDistance=DistanceX - Prec
else
    if (DistanceY - Prec) < Speed and (DistanceY - Prec) > (DistanceX - Prec) then
      GoDistance=DistanceY - Prec
       else
      GoDistance=Speed
    end if
   end if
  circle = 0
  repeat
    UO.Press(Dirs[Dir])
    timer = uo.timer() + steptimer
  repeat
    EndDir=GetDirToDir(UO.GetDir(), Prec)
    wait(DynamicPause)
  until StartDir<>EndDir or StartY<>UO.GetY() or StartX<>UO.GetX() or timer <= uo.timer()
  if StartDir<>EndDir then
  GoDistance = GoDistance + 1
  StartDir = EndDir
  end if
    circle = circle + 1
  until circle == GoDistance or GoDistance == 0 or timer <= uo.timer()
  if timer <= uo.timer() then
    return false
  else
    return true
  end if
end sub

Sub IsPass(X, Y)
  if UO.GetGlobal("BlindWalk") == "1" then
    return true
  end if
  dim Types[60]
  Types[1]=3
  Types[2]=25
  Types[3]=51
  Types[4]=63
  Types[5]=113
  Types[6]=140
  Types[7]=172
  Types[8]=219
  Types[9]=232
  Types[10]=235
  Types[11]=239
  Types[12]=243
  Types[13]=248
  Types[14]=251
  Types[15]=264
  Types[16]=267
  Types[17]=282
  Types[18]=289
  Types[19]=321
  Types[20]=379
  Types[21]=420
  Types[22]=440
  Types[23]=476
  Types[24]=499
  Types[25]=513
  Types[26]=542
  Types[27]=578
  Types[28]=586
  Types[29]=622
  Types[30]=700
  Types[31]=804
  Types[32]=1740
  Types[33]=1758
  Types[34]=1770
  Types[35]=1779
  Types[36]=1779
  Types[37]=1881
  Types[38]=1886
  Types[39]=1801
  Types[40]=1805
  Types[41]=1813
  Types[42]=1820
  Types[43]=1831
  Types[44]=1833
  Types[45]=1843
  Types[46]=1850
  Types[47]=1873
  Types[48]=1876
  Types[49]=1885
  Types[50]=1888
  Types[51]=1946
  Types[52]=1969
  Types[53]=2500
  Types[54]=2539
  for var i = 1 to 53 step 2
    if UO.PrivateGetTile(X, Y,  - 1, Types[i], Types[i + 1]) then
      return true
    end if
  next
  return false
end sub

Sub Abs(X)
  if X>0 then
    return X
  else
    return ( - X)
  end if
end sub
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Incorrect User
Posts: 949
Joined: 2011-05-23 00:33:30

Re: Сверхточная ходилка (c) Beyonder

Post by Incorrect User »

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

Так же в ходилке можно делать количество шагов на выбор, при это если количество шагов до цели меньше чем количество шагов за раз установленное нами, то ходилка сделает столько шагов сколько нужно до цели. Но сколько бы мы ни делали шагов проверка тайлов будет только одного тайла перед собой(проверили 1 тайл а шага делаем 3).

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

Это позволит заранее обходить препятствия а не упираться в них и ходьба будет более быстрой и реалистичной.

Нашел еще одну проблему, тайлы моста, их диапазон 1993-1996, но такая ситуация, чар идя по мосту доходит до определенного места и дальше начинает его обходить как будто там препятствие. infotile показывает номер тайла 1996 но при проверке того места uo.privategettile говорит что там тайл не 1996. Как это выходит я не знаю. По этому, если нужно ходить по мосту, на данный момент отключайте проверку тайлов, при ходьбе в других местах похожей проблемы не встречал.

Ходилка с настройками которые использую сейчас

Code: Select all

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; var Prec=3 # Как близко следует подойти к цели (Precision)
; В функции IsPass, содержиться список проходимых тайлов.
; Walker(X, Y, Prec) - идем к цели с координатами X, Y. Возвращает 1 в случае успешного достижения цели, и 0 - при невозможном обходе (путь не найден)
; Tracer(StartDir, Direction) - трассировка 1 шага. Возвращает направление по которому получилось сдвинуться с места. StartDir # -  направление последнего движения, Direction ( - 1 или  + 1) направление обхода.  - 1 - по часовой стрелке,  + 1 против часовой #стрелки. Направления скрипт использует личного формата:
; 1 - влево вниз
; 2 - вниз
; 3 - вправо вниз
; 4 - вправо
; 5 - вправо вверх
; 6 - вверх
; 7 - влево вверх
; 8 - влево
; Tracer(StartDir, Direction) - идеально подходит для рыбалки вдоль берега так как она будет обходить берег бесконечно (1 #запуск функции = 1 шаг обхода).
var MaxTraceDistance = 1 ; Максимальная длина обхода. Желательно ставить с расчета возможных препятсвий. Если ставить очень большие числа, кодилка может пойти в обход пол мира чтобы дойти к соседнему дереву.
var TraceLoopIncrease = 1 ; Увеличение MaxTraceDistance при исчерпании количества ходов.
var LimitTrace = 10 ; Сколько шагов в обе стороны от начальной точки обхода прекращают ходилку (выхода нет).
var Speed = 2 ; Сколько шагов делать за раз между проверками.
var DynamicPause = 70 ; Минимальные паузы в циклах. Чем меньше число - тем меньше рывков и тем больше нагрузка процессора.
var steptimer = 2 ; Таймер на шаг(Значение 1 = 100мс). Время за которое чар проходит 1 тайл, если за это время чар не сдвинется с места скрипт расценит это как препятствие и начнет обходить.
sub Walker(GoX, GoY, Prec)
  uo.setglobal("BlindWalk", "0") ; не использовать проверку тайлов, а использовать ходьбу наощупь. 0 - проверяем тайлы, 1 - не проверяем.
  var LastDir
  var MoveRes
  var TracerCnt
  uo.setglobal("GlobalGoX", str(GoX))
  uo.setglobal("GlobalGoY", str(GoY))
  while not IsEnd(GoX, GoY, Prec)
    TracerCnt = MaxTraceDistance
    repeat
      LastDir=GoUntilHit(GoX, GoY, Prec)
      if IsEnd(GoX, GoY, Prec) then
        return 1
      end if
      MoveRes = FullAroundTrace(LastDir, GoX, GoY, Prec, TracerCnt)
      if TracerCnt > LimitTrace then
        return 0
      endif
      TracerCnt = TracerCnt + TraceLoopIncrease
    until MoveRes == 1
  wend
  return 1
end sub

Sub FullAroundTrace(StartDir, GoX, GoY, Prec, MaxTrace)
  var LineX=UO.GetX()
  var LineY=UO.GetY()
  var CurDir=StartDir
  var Direction=CountDirection(GoX, GoY, CurDir, Prec)
  var StartX, StartY
  var MovesDone=0
  repeat
    StartX=UO.GetX()
    StartY=UO.GetY()
    CurDir=Tracer(CurDir, Direction, Prec)
    if (CurDir==GetDir(GoX, GoY, Prec)) then
      return 1
    endif
    if MovesDone>0 and PrevMoveCross(GetDirToDir(UO.GetDir(), Prec), LineX, LineY, GoX, GoY, StartX, StartY, Prec) then
      return 1
    end if
    MovesDone=MovesDone + 1
    CurDir=AddToDir(CurDir,  - Direction, Prec)
  until MovesDone>MaxTrace
  return 0
end sub

Sub CountDirection(GoX, GoY, StartDir, Prec)
  var GoDir=GetDir(GoX, GoY, Prec)
  var MyX=UO.GetX()
  var MyY=UO.GetY()
  if GoDir<StartDir then
    return  - 1
  end if
  if GoDir>StartDir then
    return 1
  end if
  if Abs(MyX - GoX)>Abs(MyY - GoY) then
    if (GoDir==3) or (GoDir==7) then
      return  - 1
    else
      return 1
    end if
  else
    if (GoDir==1) or (GoDir==5) then
      return  - 1
    else
      return 1
    end if
  end if
end sub

Sub PrevMoveCross(Dir, x1, y1, x2, y2, StartX, StartY, Prec)
  var x3, y3, x4, y4
  x3=StartX
  y3=StartY
  x4=StartX + (XFromDir(Dir) - StartX)*Speed
  y4=StartY + (YFromDir(Dir) - StartY)*Speed
  return LinesCrossing(x1, y1, x2, y2, x3, y3, x4, y4, Prec)
end sub

Sub LinesCrossing(x1, y1, x2, y2, x3, y3, x4, y4, Prec)
  if x1==x3 and y1==y3 then
    return false
  end if
 
  var ua1=(x4 - x3)*(y1 - y3) - (y4 - y3)*(x1 - x3)
  var ub1=(y4 - y3)*(x2 - x1) - (x4 - x3)*(y2 - y1)
 
  var ua2=(x2 - x1)*(y1 - y3) - (y2 - y1)*(x1 - x3)
  var ub2=(y4 - y3)*(x2 - x1) - (x4 - x3)*(y2 - y1)
 
  #Check for parallel lines
  if (ub1 == 0) or (ub2 == 0) then
    return false
  end if
  var u1=ua1/ub1
  var u2=ua2/ub2
 
  if IsDiap(u1, 0, 1, 0.01) and IsDiap(u2, 0, 1, 0.01) then
    return true
  else
    return false
  end if
end sub

Sub IsDiap(X, X0, X1, Prec)
  if X<=X0 + Prec and X>=X1 - Prec OR X>=X0 - Prec and X<=X1 + Prec then
    return true
  end if
  return false
end sub

Sub GoUntilHit(GoX, GoY, Prec)
  var LastDir
  LastDir=GetDir(GoX, GoY, Prec)
  var CouldMove
  repeat
    LastDir=GetDir(GoX, GoY, Prec)
    if LastDir<>0 and not IsEnd(GoX, GoY, Prec) then
      CouldMove=TryDir(LastDir, Prec)
    end if
  until LastDir==0 or IsEnd(GoX, GoY, Prec) or not CouldMove
  return LastDir
end sub

Sub IsEnd(GoX, GoY, Prec)
  if Abs(UO.GetX() - GoX)<=Prec and Abs(UO.GetY() - GoY)<=Prec then
    return true
  else
    return false
  end if
end sub

Sub GetDir(GoX, GoY, Prec)
  var MyX=UO.GetX()
  var MyY=UO.GetY()
  var DiffX=Abs(UO.GetX() - GoX)
  var DiffY=Abs(UO.GetY() - GoY)
  var GoDir=0
  if (DiffX/(DiffY + 0.1))>=2 then
    if (MyX>GoX) then
      GoDir=7
    else
      GoDir=3
    end if
  else
    if (DiffY/(DiffX + 0.1))>=2 then
      if (MyY>GoY) then
        GoDir=5
      else
        GoDir=1
      end if
    else
      if (MyX>GoX) and (MyY>GoY) then
        GoDir=6
      else
        if (MyX>GoX) and (MyY<GoY) then
          GoDir=8
        else
          if (MyX<GoX) and (MyY>GoY) then
            GoDir=4
          else
            if (MyX<GoX) and (MyY<GoY) then
              GoDir=2
            end if
          end if
        end if
      end if
    end if
  end if
  return GoDir
end sub

Sub Tracer(StartDir, Direction, Prec)
  var CurDir=StartDir
  var Result
  repeat
    Result=TryDir(CurDir, Prec)
    if not Result then
      CurDir=AddToDir(CurDir, Direction, Prec)
    end if
  until Result
  return Result
end sub

Sub AddToDir(Dir, Cnt, Prec)
  var NewDir=Dir
  NewDir=NewDir + Cnt
  while NewDir>8
    NewDir=NewDir - 8
  wend
  while NewDir<1
    NewDir=NewDir + 8
  wend
  return NewDir
end sub

Sub TryDir(Dir, Prec)
  var BegX=UO.GetX(), BegY=UO.GetY(), GoX=BegX, GoY=BegY
  GoX=XFromDir(Dir)
  GoY=YFromDir(Dir)
  if not IsPass(GoX, GoY) then
    return false
  end if
  return TurnAndGoDir(Dir, Prec)
end sub

Sub XFromDir(Dir)
  if Dir==2 or Dir==3 or Dir==4 then
    return (UO.GetX() + 1)
  end if
  if Dir==6 or Dir==7 or Dir==8 then
    return (UO.GetX() - 1)
  end if
  return (UO.GetX())
end sub

Sub YFromDir(Dir)
  if Dir==8 or Dir==1 or Dir==2 then
    return (UO.GetY() + 1)
  end if
  if Dir==4 or Dir==5 or Dir==6 then
    return (UO.GetY() - 1)
  end if
  return (UO.GetY())
end sub

Sub TurnAndGoDir(Dir, Prec)
  var StartDir=GetDirToDir(UO.GetDir(), Prec), StartX=UO.GetX(), StartY=UO.GetY(), EndDir, timer
  #Start Primary test
  if GoDir(Dir, Prec) then
      return Dir
  else
      return 0
  end if
end sub

Sub GetDirToDir(GotDir, Prec)
  var ChangedDir = - GotDir
  ChangedDir = AddToDir(ChangedDir, 5, Prec)
  return ChangedDir
end sub

Sub GoDir(Dir, Prec)
  var circle, StartDir=GetDirToDir(UO.GetDir(), Prec), StartX=UO.GetX(), StartY=UO.GetY(), EndDir, timer
  dim Dirs[9]
  Dirs[1]=35
  Dirs[2]=40
  Dirs[3]=34
  Dirs[4]=39
  Dirs[5]=33
  Dirs[6]=38
  Dirs[7]=36
  Dirs[8]=37
  var DistanceX=Abs(UO.GetX()-val(UO.GetGlobal("GlobalGoX")))
  var DistanceY=Abs(UO.GetY()-val(UO.GetGlobal("GlobalGoY")))
  var GoDistance
  if (DistanceX - Prec) < Speed and (DistanceX - Prec) > (DistanceY - Prec) then
    GoDistance=DistanceX - Prec
  else
    if (DistanceY - Prec) < Speed and (DistanceY - Prec) > (DistanceX - Prec) then
      GoDistance=DistanceY - Prec
    else
      GoDistance=Speed
    end if
  end if
  circle = 0
  repeat
    UO.Press(Dirs[Dir])
    timer = uo.timer() + steptimer
    repeat
      EndDir=GetDirToDir(UO.GetDir(), Prec)
      wait(DynamicPause)
    until StartDir<>EndDir or StartY<>UO.GetY() or StartX<>UO.GetX() or timer <= uo.timer()
    if StartDir<>EndDir then
      GoDistance = GoDistance + 1
      StartDir = EndDir
    end if
    circle = circle + 1
  until circle == GoDistance or GoDistance == 0 or timer <= uo.timer()
  if timer <= uo.timer() then
    return false
  else
    return true
  end if
end sub

Sub IsPass(X, Y)
  if UO.GetGlobal("BlindWalk") == "1" then
    return true
  end if
  dim Types[54]
  Types[1]=3
  Types[2]=25
  Types[3]=51
  Types[4]=63
  Types[5]=113
  Types[6]=140
  Types[7]=172
  Types[8]=219
  Types[9]=232
  Types[10]=235
  Types[11]=239
  Types[12]=243
  Types[13]=248
  Types[14]=251
  Types[15]=264
  Types[16]=267
  Types[17]=282
  Types[18]=289
  Types[19]=321
  Types[20]=379
  Types[21]=420
  Types[22]=440
  Types[23]=476
  Types[24]=499
  Types[25]=513
  Types[26]=542
  Types[27]=578
  Types[28]=586
  Types[29]=622
  Types[30]=700
  Types[31]=804
  Types[32]=1740
  Types[33]=1758
  Types[34]=1770
  Types[35]=1779
  Types[36]=1779
  Types[37]=1881
  Types[38]=1886
  Types[39]=1801
  Types[40]=1805
  Types[41]=1813
  Types[42]=1820
  Types[43]=1831
  Types[44]=1833
  Types[45]=1843
  Types[46]=1850
  Types[47]=1873
  Types[48]=1876
  Types[49]=1885
  Types[50]=1888
  Types[51]=1946
  Types[52]=1969
  Types[53]=2500
  Types[54]=2539
  for var i = 1 to 53 step 2
    if UO.PrivateGetTile(X, Y,  - 1, Types[i], Types[i + 1]) then
      return true
    end if
  next
  return false
end sub

Sub Abs(X)
  if X>0 then
    return X
  else
    return ( - X)
  end if
end sub
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Mirage
Posts: 2802
Joined: 2009-05-28 09:58:28
Location: Иваново
Contact:

Re: Сверхточная ходилка (c) Beyonder

Post by Mirage »

Фиг знает.
1) на инжекте в принципе ходилку сделать жизнеспособную это быть вундеркиндом или автором инжекта.
2) я на этой ходиле держал бота на охоту, шахтера и крафтовые заказы относил. Пробовал автодогон врубать - бегал по 10-15 минут город/лес/поле/пещеры - в 4 случаях из 5 попыток догонялка прибежал за догоняемым чаром. Иногда упирался в невидимые тайлы или просто не мог вылезти из "вилки" или угла.
3) не видимые тайлы это есть ловушка либо косяк администратора шарда и авторов игры (видел бы ты какие дыры и косяки в дефолтном клиенте присутствуют со статикой). В статике прописан куст а в вердате или на карте его нет. И игрок думает что куста нет хотя он на самом деле есть.
4) у этой ходилки проблема с телепортами есть. Забегать в гейты она не умеет или умеет плохо.
5) Если надо пройти мост ставь одну точку в начале и вторую в конце. Чар сам дойдет куда надо. А потеля 1-3 шагов не существенна при автономном боте. На ПВП ходилки использовать не комильфо. Бегать нужно руками.

ЗЫ самый лучший вариант - смесь бегалки на изиуо и совершения действий на инжекте. А лучше добычу на стелсе держать. Тогда чара хоть на сотовом телефоне можно запускать и держать. Но я ведь это уже писал ;)
Incorrect User
Posts: 949
Joined: 2011-05-23 00:33:30

Re: Сверхточная ходилка (c) Beyonder

Post by Incorrect User »

Смысл не сделать идеальную ходилку, смысл выжать все что можно из того что есть, а больше и не нужно. Проверку 3-х тайлов вместо я сейчас попробую сделать сам, проверю как будет ходить. А изи уо я даже не знаю что это такое, поэтому мне нет до него дела.
Incorrect User
Posts: 949
Joined: 2011-05-23 00:33:30

Re: Сверхточная ходилка (c) Beyonder

Post by Incorrect User »

Сделал чтобы проверял столько раз сколько нужно сделать шагов. Но беда с инфотайлом, стою прямо перед деревом или кустом или камнем а он показывает что там проходимый тайл. Так же стою на открытом месте, там номера тайла 0, и он тоже показывает что проходимое место, хотя в списке проходимые тайлы начинаются с 3. Короче инфотайл работает только на мосту и то неправильно.
Juicy Fruit
Posts: 820
Joined: 2011-06-11 19:54:23

Re: Сверхточная ходилка (c) Beyonder

Post by Juicy Fruit »

Code: Select all

3289 880 1905 0 - Дерево
6012 879 1901 0 - Камень
3391 881 1906 0 - Куст
Инфотайл показывает статику. Если через инсайдУО смотреть - Artwork->Static Tiles то все верно показывает. Чтоб Landscape Tiles узнать - надо обращаться к разработчикам инжекта или в личку мне напиши, суну функцию в скриптовый модуль.
Incorrect User
Posts: 949
Joined: 2011-05-23 00:33:30

Re: Сверхточная ходилка (c) Beyonder

Post by Incorrect User »

Очевидно у нас на шарде privategettile не работает, вырезал полностью часть с его использованием - ходьба не изменилась. Пример, стою перед камнем, его номер 6004, проверяю тайл

Code: Select all

var x, y
  x = uo.getx() - 1
  y = uo.gety()
  if UO.PrivateGetTile(x, y, -1, 3, 6) then
        uo.print("OK!")
   else
   uo.print("False!")
    end if

То есть проверяем диапазон номеров от 3 по 6 а у камня номер 6004, и он пишет OK! типа в месте поиска есть тайл из диапазона 3-6. Пробовал 3-3 3-4 3-5... пишет ОК когда есть номер 4 в диапазоне например если будет 0-3 или 5-3000 то напишет false. Выходит на этом месте тайл номер 4, таким его видит privategettile, а тайл номер 4 в ходилке считается проходимым.

Code: Select all

  Types[1]=3
  Types[2]=25

Что это за дела? Выходит он видит тайлы но какие-то свои номера?
Juicy Fruit
Posts: 820
Joined: 2011-06-11 19:54:23

Re: Сверхточная ходилка (c) Beyonder

Post by Juicy Fruit »

На сколько я помню - PrivateGetTile видит какраз Landscape Tiles. Статику игнорит, но могу ошибаться.
Incorrect User
Posts: 949
Joined: 2011-05-23 00:33:30

Re: Сверхточная ходилка (c) Beyonder

Post by Incorrect User »

Смотри что получается, похоже он видит и статику и то что ты сказал, так как я только что проверил и именно тайл 6004 он тоже пишет ОК!. Получается косяк, и нужно вписывать непроходимую статику вместо проходимых тайлов, так как если мы проверяем на тайл место с тайлом и в списке проходимых тайлов статики будет тайл с номером как у Landscape Tiles на том же месте то он нам и покажет что место свободно. Нужно менять список проходимой статики на непроходимую и он нам бут показывать правильно. Со списком не поможете товарищи? :roll:
Incorrect User
Posts: 949
Joined: 2011-05-23 00:33:30

Re: Сверхточная ходилка (c) Beyonder

Post by Incorrect User »

Текущий вариант, количество проверяемых тайлов теперь не 1 а столько сколько чар должен сделать. Рабочая проверка тайлов, в списке тайлы деревьев, тайлы камней, тайлы пеньков(которые не рубятся), и некоторые тайлы скал. Выбирал те которые встречаются в лесу. Добавляйте, расширяйте, тестируйте.

Code: Select all

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; var Prec=3 # Как близко следует подойти к цели (Precision)
; В функции IsPass, содержиться список проходимых тайлов.
; Walker(X, Y, Prec) - идем к цели с координатами X, Y. Возвращает 1 в случае успешного достижения цели, и 0 - при невозможном обходе (путь не найден)
; Tracer(StartDir, Direction) - трассировка 1 шага. Возвращает направление по которому получилось сдвинуться с места. StartDir # -  направление последнего движения, Direction ( - 1 или  + 1) направление обхода.  - 1 - по часовой стрелке,  + 1 против часовой #стрелки. Направления скрипт использует личного формата:
; 1 - влево вниз
; 2 - вниз
; 3 - вправо вниз
; 4 - вправо
; 5 - вправо вверх
; 6 - вверх
; 7 - влево вверх
; 8 - влево
; Tracer(StartDir, Direction) - идеально подходит для рыбалки вдоль берега так как она будет обходить берег бесконечно (1 #запуск функции = 1 шаг обхода).
var MaxTraceDistance = 2 ; Максимальная длина обхода. Желательно ставить с расчета возможных препятсвий. Если ставить очень большие числа, кодилка может пойти в обход пол мира чтобы дойти к соседнему дереву.
var TraceLoopIncrease = 1 ; Увеличение MaxTraceDistance при исчерпании количества ходов.
var LimitTrace = 10 ; Сколько шагов в обе стороны от начальной точки обхода прекращают ходилку (выхода нет).
var Speed = 3 ; Сколько шагов делать за раз между проверками.
var DynamicPause = 30 ; Минимальные паузы в циклах. Чем меньше число - тем меньше рывков и тем больше нагрузка процессора.
var steptimer = 2 ; Таймер на шаг(Значение 1 = 100мс). Время за которое чар проходит 1 тайл, если за это время чар не сдвинется с места скрипт расценит это как препятствие и начнет обходить.
sub Walker(GoX, GoY, Prec)
  uo.setglobal("BlindWalk", "0") ; не использовать проверку тайлов, а использовать ходьбу наощупь. 0 - проверяем тайлы, 1 - не проверяем.
  var LastDir
  var MoveRes
  var TracerCnt
  uo.setglobal("GlobalGoX", str(GoX))
  uo.setglobal("GlobalGoY", str(GoY))
  while not IsEnd(GoX, GoY, Prec)
    TracerCnt = MaxTraceDistance
    repeat
      LastDir=GoUntilHit(GoX, GoY, Prec)
      if IsEnd(GoX, GoY, Prec) then
        return 1
      end if
      MoveRes = FullAroundTrace(LastDir, GoX, GoY, Prec, TracerCnt)
      if TracerCnt > LimitTrace then
        return 0
      endif
      TracerCnt = TracerCnt + TraceLoopIncrease
    until MoveRes == 1
  wend
  return 1
end sub

sub FullAroundTrace(StartDir, GoX, GoY, Prec, MaxTrace)
  var LineX=UO.GetX()
  var LineY=UO.GetY()
  var CurDir=StartDir
  var Direction=CountDirection(GoX, GoY, CurDir, Prec)
  var StartX, StartY
  var MovesDone=0
  repeat
    StartX=UO.GetX()
    StartY=UO.GetY()
    CurDir=Tracer(CurDir, Direction, Prec)
    if (CurDir==GetDir(GoX, GoY, Prec)) then
      return 1
    endif
    if MovesDone>0 and PrevMoveCross(GetDirToDir(UO.GetDir(), Prec), LineX, LineY, GoX, GoY, StartX, StartY, Prec) then
      return 1
    end if
    MovesDone=MovesDone + 1
    CurDir=AddToDir(CurDir,  - Direction, Prec)
  until MovesDone>MaxTrace
  return 0
end sub

sub CountDirection(GoX, GoY, StartDir, Prec)
  var GoDir=GetDir(GoX, GoY, Prec)
  var MyX=UO.GetX()
  var MyY=UO.GetY()
  if GoDir<StartDir then
    return  - 1
  end if
  if GoDir>StartDir then
    return 1
  end if
  if Abs(MyX - GoX)>Abs(MyY - GoY) then
    if (GoDir==3) or (GoDir==7) then
      return  - 1
    else
      return 1
    end if
  else
    if (GoDir==1) or (GoDir==5) then
      return  - 1
    else
      return 1
    end if
  end if
end sub

sub PrevMoveCross(Dir, x1, y1, x2, y2, StartX, StartY, Prec)
  var x3, y3, x4, y4
  x3=StartX
  y3=StartY
  x4=StartX + (XFromDir(Dir) - StartX)*Speed
  y4=StartY + (YFromDir(Dir) - StartY)*Speed
  return LinesCrossing(x1, y1, x2, y2, x3, y3, x4, y4, Prec)
end sub

sub LinesCrossing(x1, y1, x2, y2, x3, y3, x4, y4, Prec)
  if x1==x3 and y1==y3 then
    return false
  end if
 
  var ua1=(x4 - x3)*(y1 - y3) - (y4 - y3)*(x1 - x3)
  var ub1=(y4 - y3)*(x2 - x1) - (x4 - x3)*(y2 - y1)
 
  var ua2=(x2 - x1)*(y1 - y3) - (y2 - y1)*(x1 - x3)
  var ub2=(y4 - y3)*(x2 - x1) - (x4 - x3)*(y2 - y1)
 
  #Check for parallel lines
  if (ub1 == 0) or (ub2 == 0) then
    return false
  end if
  var u1=ua1/ub1
  var u2=ua2/ub2
 
  if IsDiap(u1, 0, 1, 0.01) and IsDiap(u2, 0, 1, 0.01) then
    return true
  else
    return false
  end if
end sub

sub IsDiap(X, X0, X1, Prec)
  if X<=X0 + Prec and X>=X1 - Prec OR X>=X0 - Prec and X<=X1 + Prec then
    return true
  end if
  return false
end sub

sub GoUntilHit(GoX, GoY, Prec)
  var LastDir
  LastDir=GetDir(GoX, GoY, Prec)
  var CouldMove
  repeat
    LastDir=GetDir(GoX, GoY, Prec)
    if LastDir<>0 and not IsEnd(GoX, GoY, Prec) then
      CouldMove=TryDir(LastDir, Prec)
    end if
  until LastDir==0 or IsEnd(GoX, GoY, Prec) or not CouldMove
  return LastDir
end sub

sub IsEnd(GoX, GoY, Prec)
  if Abs(UO.GetX() - GoX)<=Prec and Abs(UO.GetY() - GoY)<=Prec then
    return true
  else
    return false
  end if
end sub

sub GetDir(GoX, GoY, Prec)
  var MyX=UO.GetX()
  var MyY=UO.GetY()
  var DiffX=Abs(UO.GetX() - GoX)
  var DiffY=Abs(UO.GetY() - GoY)
  var GoDir=0
  if (DiffX/(DiffY + 0.1))>=2 then
    if (MyX>GoX) then
      GoDir=7
    else
      GoDir=3
    end if
  else
    if (DiffY/(DiffX + 0.1))>=2 then
      if (MyY>GoY) then
        GoDir=5
      else
        GoDir=1
      end if
    else
      if (MyX>GoX) and (MyY>GoY) then
        GoDir=6
      else
        if (MyX>GoX) and (MyY<GoY) then
          GoDir=8
        else
          if (MyX<GoX) and (MyY>GoY) then
            GoDir=4
          else
            if (MyX<GoX) and (MyY<GoY) then
              GoDir=2
            end if
          end if
        end if
      end if
    end if
  end if
  return GoDir
end sub

sub Tracer(StartDir, Direction, Prec)
  var CurDir=StartDir
  var Result
  repeat
    Result=TryDir(CurDir, Prec)
    if not Result then
      CurDir=AddToDir(CurDir, Direction, Prec)
    end if
  until Result
  return Result
end sub

sub AddToDir(Dir, Cnt, Prec)
  var NewDir=Dir
  NewDir=NewDir + Cnt
  while NewDir>8
    NewDir=NewDir - 8
  wend
  while NewDir<1
    NewDir=NewDir + 8
  wend
  return NewDir
end sub

sub TryDir(Dir, Prec)
  var i, BegX=UO.GetX(), BegY=UO.GetY(), GoX=BegX, GoY=BegY, GoDistance, DistanceX=Abs(UO.GetX()-val(UO.GetGlobal("GlobalGoX"))), DistanceY=Abs(UO.GetY()-val(UO.GetGlobal("GlobalGoY")))
  if (DistanceX - Prec) < Speed and (DistanceX - Prec) > (DistanceY - Prec) then
    GoDistance=DistanceX - Prec
  else
    if (DistanceY - Prec) < Speed and (DistanceY - Prec) > (DistanceX - Prec) then
      GoDistance=DistanceY - Prec
    else
      GoDistance=Speed
    end if
  end if
  if GoDistance > 1 then
    GoX=XFromDir(Dir)
    GoY=YFromDir(Dir)
    for i = 1 to GoDistance
      if GoX < uo.getx() then
        GoX = uo.getx() - 1
      end if
      if GoX > uo.getx() then
        GoX = uo.getx() + 1
      end if
      if GoY < uo.gety() then
        GoY = uo.gety() - 1
      end if
      if GoY > uo.gety() then
        GoY = uo.gety() + 1
      end if
      if not IsPass(GoX, GoY) then
        return false
      end if
    next
  else
    GoX=XFromDir(Dir)
    GoY=YFromDir(Dir)
    if not IsPass(GoX, GoY) then
      return false
    end if
  end if
  return TurnAndGoDir(Dir, Prec)
end sub

sub XFromDir(Dir)
  if Dir==2 or Dir==3 or Dir==4 then
    return (UO.GetX() + 1)
  end if
  if Dir==6 or Dir==7 or Dir==8 then
    return (UO.GetX() - 1)
  end if
  return (UO.GetX())
end sub

sub YFromDir(Dir)
  if Dir==8 or Dir==1 or Dir==2 then
    return (UO.GetY() + 1)
  end if
  if Dir==4 or Dir==5 or Dir==6 then
    return (UO.GetY() - 1)
  end if
  return (UO.GetY())
end sub

sub TurnAndGoDir(Dir, Prec)
  var StartDir=GetDirToDir(UO.GetDir(), Prec), StartX=UO.GetX(), StartY=UO.GetY(), EndDir, timer
  #Start Primary test
  if GoDir(Dir, Prec) then
      return Dir
  else
      return 0
  end if
end sub

sub GetDirToDir(GotDir, Prec)
  var ChangedDir = - GotDir
  ChangedDir = AddToDir(ChangedDir, 5, Prec)
  return ChangedDir
end sub

sub GoDir(Dir, Prec)
  var circle, StartDir=GetDirToDir(UO.GetDir(), Prec), StartX=UO.GetX(), StartY=UO.GetY(), EndDir, timer
  dim Dirs[9]
  Dirs[1]=35
  Dirs[2]=40
  Dirs[3]=34
  Dirs[4]=39
  Dirs[5]=33
  Dirs[6]=38
  Dirs[7]=36
  Dirs[8]=37
  var DistanceX=Abs(UO.GetX()-val(UO.GetGlobal("GlobalGoX")))
  var DistanceY=Abs(UO.GetY()-val(UO.GetGlobal("GlobalGoY")))
  var GoDistance
  if (DistanceX - Prec) < Speed and (DistanceX - Prec) > (DistanceY - Prec) then
    GoDistance=DistanceX - Prec
  else
    if (DistanceY - Prec) < Speed and (DistanceY - Prec) > (DistanceX - Prec) then
      GoDistance=DistanceY - Prec
    else
      GoDistance=Speed
    end if
  end if
  circle = 0
  repeat
    UO.Press(Dirs[Dir])
    timer = uo.timer() + steptimer
    repeat
      EndDir=GetDirToDir(UO.GetDir(), Prec)
      wait(DynamicPause)
    until StartDir<>EndDir or StartY<>UO.GetY() or StartX<>UO.GetX() or timer <= uo.timer()
    if StartDir<>EndDir then
      GoDistance = GoDistance + 1
      StartDir = EndDir
    end if
    circle = circle + 1
  until circle == GoDistance or GoDistance == 0 or timer <= uo.timer()
  if timer <= uo.timer() then
    return false
  else
    return true
  end if
end sub

sub IsPass(X, Y)
  if UO.GetGlobal("BlindWalk") == "1" then
    return true
  end if
  dim Types[54]
  Types[1]=3391
  Types[2]=3392
  Types[3]=3305
  Types[4]=3306
  Types[5]=3230
  Types[6]=3230
  Types[7]=4792
  Types[8]=4795
  Types[9]=3393
  Types[10]=3396
  Types[11]=3415
  Types[12]=3419
  Types[13]=3438
  Types[14]=3442
  Types[15]=3460
  Types[16]=3462
  Types[17]=3280
  Types[18]=3280
  Types[19]=3277
  Types[20]=3277
  Types[21]=3283
  Types[22]=3283
  Types[23]=3286
  Types[24]=3286
  Types[25]=3289
  Types[26]=3289
  Types[27]=3291
  Types[28]=3291
  Types[29]=3294
  Types[30]=3294
  Types[31]=3296
  Types[32]=3296
  Types[33]=3299
  Types[34]=3299
  Types[35]=3302
  Types[36]=3302
  Types[37]=3290
  Types[38]=3290
  Types[39]=3288
  Types[40]=3288
  Types[41]=3320
  Types[42]=3329
  Types[43]=6001
  Types[44]=6012
  Types[45]=2272
  Types[46]=2282
  Types[47]=1873
  Types[48]=1876
  Types[49]=1885
  Types[50]=1888
  Types[51]=1946
  Types[52]=1969
  Types[53]=2500
  Types[54]=2539
  for var i = 1 to 45 step 2
    if UO.PrivateGetTile(X, Y,  - 1, Types[i], Types[i + 1]) then
      return false
    end if
  next
  return true
end sub

sub Abs(X)
  if X>0 then
    return X
  else
    return ( - X)
  end if
end sub
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Mirage
Posts: 2802
Joined: 2009-05-28 09:58:28
Location: Иваново
Contact:

Re: Сверхточная ходилка (c) Beyonder

Post by Mirage »

for var i = 1 to 45 step 2
if UO.PrivateGetTile(X, Y, - 1, Types[i], Types[i + 1]) then

наверное не 45 а больше?
Ты ведь для редактирования вот ЭТОТ пост используешь?
Incorrect User
Posts: 949
Joined: 2011-05-23 00:33:30

Re: Сверхточная ходилка (c) Beyonder

Post by Incorrect User »

Нет, из первого поста брал. 45, дальше 46 значения старые. Хотя я прикинул, получается все значения препятствий выше 3000, так что смело можно одну строку влепить и хватит, но это пока в виде идеи. Если в той что то лучше то части я заменю, в принципе я заменю от туда все кроме того что уже рабочее и исправленное из старой здесь.
Incorrect User
Posts: 949
Joined: 2011-05-23 00:33:30

Re: Сверхточная ходилка (c) Beyonder

Post by Incorrect User »

У воды тайлы от 6***, одна проблема в копалке тайлы черного места, нужен их номер Landscape Tiles.
Incorrect User
Posts: 949
Joined: 2011-05-23 00:33:30

Re: Сверхточная ходилка (c) Beyonder

Post by Incorrect User »

Текущий вариант, заменил части на новые из поста, изменил проверку тайлов вместо массива одна строка if UO.PrivateGetTile(X, Y, -1, 2540(последнее значение из списка проходимых тайлов старой ходилки - 2539), 7000) then

Code: Select all

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; var Prec=3 # Как близко следует подойти к цели (Precision)
; В функции IsPass, содержиться список проходимых тайлов.
; Walker(X, Y, Prec) - идем к цели с координатами X, Y. Возвращает 1 в случае успешного достижения цели, и 0 - при невозможном обходе (путь не найден)
; Tracer(StartDir, Direction) - трассировка 1 шага. Возвращает направление по которому получилось сдвинуться с места. StartDir # -  направление последнего движения, Direction ( - 1 или  + 1) направление обхода.  - 1 - по часовой стрелке,  + 1 против часовой #стрелки. Направления скрипт использует личного формата:
; 1 - влево вниз
; 2 - вниз
; 3 - вправо вниз
; 4 - вправо
; 5 - вправо вверх
; 6 - вверх
; 7 - влево вверх
; 8 - влево
; Tracer(StartDir, Direction) - идеально подходит для рыбалки вдоль берега так как она будет обходить берег бесконечно (1 #запуск функции = 1 шаг обхода).
var MaxTraceDistance = 2 ; Максимальная длина обхода. Желательно ставить с расчета возможных препятсвий. Если ставить очень большие числа, кодилка может пойти в обход пол мира чтобы дойти к соседнему дереву.
var TraceLoopIncrease = 1 ; Увеличение MaxTraceDistance при исчерпании количества ходов.
var LimitTrace = 10 ; Сколько шагов в обе стороны от начальной точки обхода прекращают ходилку (выхода нет).
var Speed = 3 ; Сколько шагов делать за раз между проверками.
var DynamicPause = 30 ; Минимальные паузы в циклах. Чем меньше число - тем меньше рывков и тем больше нагрузка процессора.
var steptimer = 2 ; Таймер на шаг(Значение 1 = 100мс). Время за которое чар проходит 1 тайл, если за это время чар не сдвинется с места скрипт расценит это как препятствие и начнет обходить.

sub Walker(GoX, GoY, Prec)
  uo.setglobal("BlindWalk", "0") ; не использовать проверку тайлов, а использовать ходьбу наощупь. 0 - проверяем тайлы, 1 - не проверяем.
  var LastDir
  var MoveRes
  var TracerCnt
  uo.setglobal("GlobalGoX", str(GoX))
  uo.setglobal("GlobalGoY", str(GoY))
  while not IsEnd(GoX,GoY,Prec)
    TracerCnt = MaxTraceDistance
    repeat
      LastDir=GoUntilHit(GoX,GoY,Prec)
      if IsEnd(GoX,GoY,Prec) then
        return 1
      end if
      MoveRes = FullAroundTrace(LastDir,GoX,GoY,Prec,TracerCnt)
      if TracerCnt > LimitTrace then
        return 0
      endif
      TracerCnt = TracerCnt + TraceLoopIncrease
    until MoveRes == 1
  wend
  return 1
end sub

sub FullAroundTrace(StartDir,GoX,GoY,Prec,MaxTrace)
  var LineX=UO.GetX()
  var LineY=UO.GetY()
  var CurDir=StartDir
  var Direction=CountDirection(GoX,GoY,CurDir,Prec)
  var StartX,StartY
  var MovesDone=0
  repeat
    StartX=UO.GetX()
    StartY=UO.GetY()
    CurDir=Tracer(CurDir,Direction,Prec)
    if (CurDir==GetDir(GoX,GoY,Prec)) then
      return 1
    endif
    if MovesDone>0 and PrevMoveCross(GetDirToDir(UO.GetDir(),Prec),LineX,LineY,GoX,GoY,StartX,StartY,Prec) then
      return 1
    end if
    MovesDone=MovesDone+1
    CurDir=AddToDir(CurDir,-Direction,Prec)
  until MovesDone>MaxTrace
  return 0
end sub

sub CountDirection(GoX,GoY,StartDir,Prec)
  var GoDir=GetDir(GoX,GoY,Prec)
  var MyX=UO.GetX()
  var MyY=UO.GetY()
  if GoDir<StartDir then
    return -1
  end if
  if GoDir>StartDir then
    return 1
  end if
  if Abs(MyX-GoX)>Abs(MyY-GoY) then
    if (GoDir==3) OR (GoDir==7) then
      return -1
    else
      return 1
    end if
  else
    if (GoDir==1) or (GoDir==5) then
      return -1
    else
      return 1
    end if
  end if
end sub

sub PrevMoveCross(Dir,x1,y1,x2,y2,StartX,StartY,Prec)
  var x3,y3,x4,y4
  x3=StartX
  y3=StartY
  x4=StartX+(XFromDir(Dir)-StartX)*Speed
  y4=StartY+(YFromDir(Dir)-StartY)*Speed
  return LinesCrossing(x1,y1,x2,y2,x3,y3,x4,y4,Prec)
end sub

sub LinesCrossing(x1,y1,x2,y2,x3,y3,x4,y4,Prec)
  if x1==x3 and y1==y3 then
    return false
  end if
  var ua1=(x4-x3)*(y1-y3)-(y4-y3)*(x1-x3)
  var ub1=(y4-y3)*(x2-x1)-(x4-x3)*(y2-y1)
  var ua2=(x2-x1)*(y1-y3)-(y2-y1)*(x1-x3)
  var ub2=(y4-y3)*(x2-x1)-(x4-x3)*(y2-y1)
  #Check for parallel lines
  if (ub1 == 0) or (ub2 == 0) then
    return false
  end if
  var u1=ua1/ub1
  var u2=ua2/ub2
  if IsDiap(u1,0,1,0.01) and IsDiap(u2,0,1,0.01) then
    return true
  else
    return false
  end if
end sub

sub IsDiap(X,X0,X1,Prec)
  if X<=X0+Prec and X>=X1-Prec OR X>=X0-Prec and X<=X1+Prec then
    return true
  end if
  return false
end sub

sub GoUntilHit(GoX,GoY,Prec)
  var LastDir
  LastDir=GetDir(GoX,GoY,Prec)
  var CouldMove
  repeat
    LastDir=GetDir(GoX,GoY,Prec)
    if LastDir<>0 and not IsEnd(GoX,GoY,Prec) then
      CouldMove=TryDir(LastDir,Prec)
    end if
  until LastDir==0 or IsEnd(GoX,GoY,Prec) or not CouldMove
  return LastDir
end sub

sub IsEnd(GoX,GoY,Prec)
  if Abs(UO.GetX()-GoX)<=Prec and Abs(UO.GetY()-GoY)<=Prec then
    return true
  else
    return false
  end if
end sub

sub GetDir(GoX,GoY,Prec)
  var MyX=UO.GetX()
  var MyY=UO.GetY()
  var DiffX=Abs(UO.GetX()-GoX)
  var DiffY=Abs(UO.GetY()-GoY)
  var GoDir=0
  if (DiffX/(DiffY+0.1))>=2 then
    if (MyX>GoX) then
      GoDir=7
    else
      GoDir=3
    end if
  else
    if (DiffY/(DiffX+0.1))>=2 then
      if (MyY>GoY) then
        GoDir=5
      else
        GoDir=1
      end if
    else
      if (MyX>GoX) and (MyY>GoY) then
        GoDir=6
      else
        if (MyX>GoX) and (MyY<GoY) then
          GoDir=8
        else
          if (MyX<GoX) and (MyY>GoY) then
            GoDir=4
          else
            if (MyX<GoX) and (MyY<GoY) then
              GoDir=2
            end if
          end if
        end if
      end if
    end if
  end if
  return GoDir
end sub

sub Tracer(StartDir,Direction,Prec)
  var CurDir=StartDir
  var Result
  repeat
    Result=TryDir(CurDir,Prec)
    if not Result then
      CurDir=AddToDir(CurDir,Direction,Prec)
    end if
  until Result
  return Result
end sub

sub AddToDir(Dir,Cnt,Prec)
  var NewDir=Dir
  NewDir=NewDir+Cnt
  while NewDir>8
    NewDir=NewDir-8
  wend
  while NewDir<1
    NewDir=NewDir+8
  wend
  return NewDir
end sub

sub TryDir(Dir, Prec)
  var BegX=UO.GetX(), BegY=UO.GetY(), GoX=BegX, GoY=BegY
    GoX=XFromDir(Dir)
    GoY=YFromDir(Dir)
    if not IsPass(GoX, GoY) then
      return false
    end if
  return TurnAndGoDir(Dir, Prec)
end sub

sub XFromDir(Dir)
  if Dir==2 or Dir==3 or Dir==4 then
    return (UO.GetX() + 1)
  end if
  if Dir==6 or Dir==7 or Dir==8 then
    return (UO.GetX() - 1)
  end if
  return (UO.GetX())
end sub

sub YFromDir(Dir)
  if Dir==8 or Dir==1 or Dir==2 then
    return (UO.GetY() + 1)
  end if
  if Dir==4 or Dir==5 or Dir==6 then
    return (UO.GetY() - 1)
  end if
  return (UO.GetY())
end sub

sub TurnAndGoDir(Dir, Prec)
  var StartDir=GetDirToDir(UO.GetDir(), Prec), StartX=UO.GetX(), StartY=UO.GetY(), EndDir, timer
  #Start Primary test
  if GoDir(Dir, Prec) then
    return Dir
  else
    return 0
  end if
end sub

sub GetDirToDir(GotDir,Prec)
  var ChangedDir=-GotDir
  ChangedDir=AddToDir(ChangedDir,5,Prec)
  return ChangedDir
end sub

sub GoDir(Dir, Prec)
  var circle, StartDir=GetDirToDir(UO.GetDir(), Prec), StartX=UO.GetX(), StartY=UO.GetY(), EndDir, timer
  dim Dirs[9]
  Dirs[1]=35
  Dirs[2]=40
  Dirs[3]=34
  Dirs[4]=39
  Dirs[5]=33
  Dirs[6]=38
  Dirs[7]=36
  Dirs[8]=37
  var DistanceX=Abs(UO.GetX()-val(UO.GetGlobal("GlobalGoX")))
  var DistanceY=Abs(UO.GetY()-val(UO.GetGlobal("GlobalGoY")))
  var GoDistance
  if (DistanceX - Prec) < Speed and (DistanceX - Prec) > (DistanceY - Prec) then
    GoDistance=DistanceX - Prec
  else
    if (DistanceY - Prec) < Speed and (DistanceY - Prec) > (DistanceX - Prec) then
      GoDistance=DistanceY - Prec
    else
      GoDistance=Speed
    end if
  end if
  circle = 0
  repeat
    UO.Press(Dirs[Dir])
    timer = uo.timer() + steptimer
    repeat
      EndDir=GetDirToDir(UO.GetDir(), Prec)
      wait(DynamicPause)
    until StartDir<>EndDir or StartY<>UO.GetY() or StartX<>UO.GetX() or timer <= uo.timer()
    if StartDir<>EndDir then
      GoDistance = GoDistance + 1
      StartDir = EndDir
    end if
    circle = circle + 1
  until circle == GoDistance or GoDistance == 0 or timer <= uo.timer()
  if timer <= uo.timer() then
    return false
  else
    return true
  end if
end sub

sub IsPass(X, Y)
  if UO.GetGlobal("BlindWalk") == "1" then
    return true
  end if
  if UO.PrivateGetTile(X, Y,  -1, 2540, 13571) or (UO.PrivateGetTile(X, Y,  -1, 500,600) and not UO.PrivateGetTile(X, Y,  -1, 0, 499) and not UO.PrivateGetTile(X, Y,  -1, 601, 13571)) then
    return false
  else
    return true
  end if
end sub

sub Abs(X)
  if X>0 then
    return X
  else
    return ( - X)
  end if
end sub
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Last edited by Incorrect User on 2013-06-17 05:18:01, edited 3 times in total.
Incorrect User
Posts: 949
Joined: 2011-05-23 00:33:30

Re: Сверхточная ходилка (c) Beyonder

Post by Incorrect User »

Нашел непроходимые тайлы ниже 3000 которые могут встретится в лесу или шахте только камни 11 тайлов, добавил в пост выше if UO.PrivateGetTile(X, Y, -1, 2540, 7000) or UO.PrivateGetTile(X, Y, -1, 2272, 2282) then
Incorrect User
Posts: 949
Joined: 2011-05-23 00:33:30

Re: Сверхточная ходилка (c) Beyonder

Post by Incorrect User »

Пока все нормально, один вопрос остался как определить номер черного места в шахте и прокатит ли с ним что нибудь сделать.
Incorrect User
Posts: 949
Joined: 2011-05-23 00:33:30

Re: Сверхточная ходилка (c) Beyonder

Post by Incorrect User »

Пока пришел к завершению, определяет черное место в шахтах, так же черное место в данже(проверял только в одном) у него другой номер тайла. Так же определяет что нет прохода по скале снаружи, все эти тайлы скалы и черный мест были в диапазоне от 500 до 600, причем некоторые всего 1 значение поэтому я взял диапазон пошире. Так же нашел одно место там проход свободный, тайл определяется как 4 и хотя он должен показываться как свободный проход он видит его как закрытое место, видимо его второе значение статики совпадает с тем что указано в проверке, такой момент был еще с одним местом, его я исправил, этот поправлю пожже, нужно отдохнуть :roll: Вот такая вышла проверка, добавил в основной скрипт выше

Code: Select all

if UO.PrivateGetTile(X, Y,  -1, 2540, 13571) or (UO.PrivateGetTile(X, Y,  -1, 500,600) and not UO.PrivateGetTile(X, Y,  -1, 0, 499) and not UO.PrivateGetTile(X, Y,  -1, 601, 13571)) then
Post Reply