Помощь - Поиск - Пользователи - Календарь
Полная версия: Автохилер ВоВ 2.4.3
UoKit.com Форумы > Кликер > UO Pilot > UO Pilot в онлайн играх
Alfer
Итак есть интерес нарисовать хилера.

Формально от 1 до 5 разных окон запущенного клиента из одной и той же папки.
Система Win7 x64.
Клиент "WoW 2.4.3 build 8606 Jul 10 2008"

Для начала беру 2 окна.
Для двух окон родился код через поиск цвета точки, что неудобно.
Код

// перед запуском скрипта прописать макросы для лечения фокуса и DD выбрать в фокус.
set #hanldewinheal 1644826 // указать хендл окна хилера
set #hanldewinDD 596864 // указать хендл окна DD
set $hppoint1 "40, 155 57344" // DD тут ткнуть Ктрл+А для указания точки срабатывания начала лечения игрока. Где-то 70-75% ХП
set $hppoint2 "39, 182 52480" // Heal тут ткнуть Ктрл+А для указания точки срабатывания начала лечения хилера. Где-то 50-70% ХП
set #tw1 0
set #gcd 1500
set #hp1 1234
set workwindow #hanldewinDD
readmem #hp1 0x24543D1C R
log #hp1
wait 40s
:check
set windowpos [1 715 [494 325 [#hanldewinheal]]]
set windowpos [69 288 [1208 753 [#hanldewinDD]]]
set workwindow #hanldewinDD
while ($hppoint1) and ($hppoint2)
if_not ($hppoint1)
goto heal_1
end_if
if_not ($hppoint2)
goto heal_2
end_if
end_while
:heal_1
set workwindow #hanldewinheal
set timer
send {num_4} #gcd
send {num_5} #gcd
set workwindow #hanldewinDD
if_not ($hppoint2)
goto heal_2
end_if
set workwindow #hanldewinDD
if ($hppoint1)
goto check
end_if
set workwindow #hanldewinheal
send {num_4} #gcd
set workwindow #hanldewinDD
if ($hppoint1)
goto check
end_if
set workwindow #hanldewinheal
send {num_4} #gcd
set workwindow #hanldewinDD
if_not ($hppoint2)
goto heal_2
end_if
set workwindow #hanldewinDD
if ($hppoint1)
goto check
end_if
set workwindow #hanldewinDD
while_not ($hppoint1)
set workwindow #hanldewinheal
send {num_6} 2000
set workwindow #hanldewinDD
if_not ($hppoint2)
goto heal_2
end_if
set workwindow #hanldewinheal
send {num_0}
if timer > 11000
set workwindow #hanldewinDD
if ($hppoint1)
goto check
end_if
goto heal_1
end_if
end_while
goto check
:heal_2
set workwindow #hanldewinheal
set timer
send {num_7} #gcd
send {num_8} #gcd
set workwindow #hanldewinDD
if_not ($hppoint1)
goto heal_1
end_if
set workwindow #hanldewinDD
if ($hppoint2)
goto check
end_if
set workwindow #hanldewinheal
send {num_7} #gcd
set workwindow #hanldewinDD
if ($hppoint2)
goto check
end_if
set workwindow #hanldewinheal
send {num_7} #gcd
set workwindow #hanldewinDD
if_not ($hppoint1)
goto heal_1
end_if
set workwindow #hanldewinDD
if ($hppoint1)
goto check
end_if
set workwindow #hanldewinDD
while_not ($hppoint2)
set workwindow #hanldewinheal
send {num_9} 2000
set workwindow #hanldewinDD
if_not ($hppoint1)
goto heal_1
end_if
set workwindow #hanldewinheal
send {num_0}
if timer > 11000
set workwindow #hanldewinDD
if ($hppoint2)
goto check
end_if
goto heal_2
end_if
end_while
goto check


Эта конструкция работает вполне сносно. Но решил углубиться в работу с памятью. Перечитал, что по-человечески нужно отталкиваться от базового адреса с цепочкой оффсетов, но пока не понял как ее отследить.

Основной алгоритм предполагается такой
пока ((ДД_ХП_актуал)\(ДД_ХП_макс) > 0.75) И ((Хил_ХП_актуал)\(Хил_ХП_МАХ) > 0.75) ждать
Иначе проверяем чьё меньше и отправляемся в процедуру его отхила.
процедура отхила ДД
процедура отхила Хила

Через ArtMoney нашёл 4 адреса(ДД хп макс и актуал, и Хил ХП макс и актуал )
Но это значение не читается в переменную
set workwindow #hanldewinDD
readmem #hp1 0x<Адресартмани> D (а Артмани тип целое 4 байта)
log #hp1
Но переменная выдает ошибку. (-1) при выводе переменной в лог

Перепробовал все возможные варианты типа данных и типа переменной всегда ошибка (-1)

Что не так подскажите куда копать в работе с памятью wow.
перечитал длинную тему про оффсеты, слазил на буржуйский форум не нашёл готовой цепочки офсетов для ХП своего и членов пати\рейда, и не нашёл механизма поиска этой цепочки. Но ведь если АртМани находит адрес памяти значит как минимум из этого адреса можно получить цифру в переменную, а вот не отдает. Подскажите куда копать ?
DarkMaster
Как раз сейчас обсуждаем с кнайтом проблему чтения памяти вова. При этом я 100% могу сказать, что память вова я читал, причем на бк. Старые версии поднимал - рабочую не нашел. Есть код на с++ который точно отрабатывает по чтению адресов вова. В данным момент данная проблема в работе.
Cockney
Чем пилот в этом плане отличается от c++?. апи то одно и тоже.
DarkMaster
Апи чего? Чтения памяти другого процесса? Это не апи. В последней бете проблема решена. Почему-то требуется двойная привязка, думаю, это будет пофиксено в ближайшее время.
Cockney
Хорошо, перефразирую. Чтение памяти вов чем-то отличается от чтения памяти других приложений ?
Alfer
Можете подсказать как искать цепочки оффсетов ?

Ищем значение, дальше вторым артмани ищем значение адреса памяти ? и из первого адреса вычитаем второй таки образом получая смещение ?
DarkMaster
артмани/читинжи. Либо сайтец по вову есть в виде форума, там кучи оффсетов.
DarkMaster
Цитата
Хорошо, перефразирую. Чтение памяти вов чем-то отличается от чтения памяти других приложений ?

Как оказалось да. Нужны некоторые дополнительные привилегии.
Alfer
А еще вопрос. есть базовый адрес приложения (wow.exe). Если их запущено несколько из одной и той же папки, у них будет одинаковый базовый адрес? И как оффсеты тогда как считать?
DarkMaster
Что есть базовый адрес? Адрес начала модуля? Может быть статикой, может быть динамикой. Если под базовым подразумевается некоторая статика с указателем, то вот пример считывания двух указателей и прибавление оффсетов:
Код
    readmem #pointer1 0xB4B2BC d
    log #pointer1  errorlevel
    set #pointer1 #pointer1 + 0x65B8
    readmem #pointer2 #pointer1 d
    log #pointer2   errorlevel
    set #pointerCam #pointer2 + 0x40
    readmem $cam #pointerCam f
    log $cam       errorlevel
Cockney
Цитата(DarkMaster @ 24.9.2016, 16:57) *

Как оказалось да. Нужны некоторые дополнительные привилегии.



Флаги доступа к процессу или что-то другое ?
DarkMaster
В общак писать не буду схему реализации. Ни к чему это. Если интересно, могу в личку.
DarkMaster
Ночная сборка b18 полный фикс.
Alfer
Спасибо, теперь память читается. А что, пилот с нецелыми числами не работает ? результат делания меньшего числа на большее - 0

К примеру в две переменные читаю максимальное и текущее значения ХП.
а дальше хочу получить цифру от 0 до 1, чтобы понять какая часть от максимального ХП осталась.

set #hp1 #hp_act / #hp_max

и тут я заметил, что переменная #hp1 не может быть дробной 0,67 например.
Т.е. пилот не работает с нецелыми числами ?
cirus
Цитата
Т.е. пилот не работает с нецелыми числами ?

Через плагин работает.
https://forum.uokit.com/index.php?showtopic=29139
Alfer
Цитата
использование чисел с плавающей точкой(в т.ч. их разницы) в пилоте
по средствам оператора if может быть не корректным.


Это как ? Т.е. может нормально работать, а может и нет ? Как раз в Ифе и использоватьсябудет. И только с ифом проблема, или с любой проверкой Например AND или XOR ?
cirus
Цитата
Т.е. может нормально работать, а может и нет ?

Код
if 10 = 10.0
   log !!!
end_if

Условие не выполнится, хотя с точки зрения математики верно.

Я бы использовал проценты, вместо сравнивания дробных чисел.
Код
set #hpmax 5000                        // максимальное хп
set #hpact 1234                        // текущее хп

set #hp1 #hpact * 100 / #hpmax         // процент хп
if #hp1 < 30                           // если хп меньше 30%
   log #hp1
end_if
end_script
Alfer
Цитата
Я бы использовал проценты, вместо сравнивания дробных чисел


Да я их использовать и хочу. Только что-то после получения нуля в делении меньшего на большее как-то не подумал множить на 100 перед делением и решил делить на 4 части и множить на 3...


Пока получается какая-то такая конструкция:

Код

Код

// перед запуском скрипта прописать макросы для лечения фокуса и лечимый объект выбрать в фокус.
// себя не лечит.
set #hanldewinheal 459404 // указать хендл окна хилера
set workwindow #hanldewinheal
set #base_adress 0x00e29d28 // базовый, где хранится адрес ячейки начала структуры чара.
readmem #first_adress #base_adress D
set #offset_maxHP_heal 0x26b0
set #offset_maxHP_DD 0x65F26B0
set #adress_maxHP_DD #first_adress + #offset_maxHP_DD //указать адрес максимального значения ХП ДДшника
set #adress_maxHP_Heal #first_adress + #offset_maxHP_heal //вычисляем адрес максимального значения ХП Хилера
set #adress_actHP_DD #adress_maxHP_DD - 0x18 //вычисляем адрес актуального значения ХП ДДшника
set #adress_actHP_Heal #adress_maxHP_Heal - 0x18 //вычисляем адрес актуального значения ХП Хиера
set #gcd 1500
log #base_adress
log #first_adress
log #adress_maxHP_Heal
//wait 40s
:0
set #mark 0
readmem #hpDD_m #adress_maxHP_DD D
readmem #hpDD_a #adress_actHP_DD D
readmem #hpheal_m #adress_maxHP_Heal D
readmem #hpheal_a #adress_actHP_Heal D
log #hpDD_m
log #hpDD_a
log #hpheal_m
log #hpheal_a
wait 40s
call hpdd_check #hpDD_m #hpDD_a
call hpheal_check #hpheal_m #hpheal_a
goto #mark
goto 0
:1
set timer
send {num_4} #gcd
send {num_5} #gcd
readmem #hpDD_m #adress_maxHP_DD D
readmem #hpDD_a #adress_actHP_DD D
set #mark 0
call hpdd_check #hpDD_m #hpDD_a
if #mark <> 1
    goto #mark
end_if
send {num_4} #gcd
readmem #hpheal_m #adress_maxHP_Heal D
readmem #hpheal_a #adress_actHP_Heal D
set #mark 0
call hpheal_check #hpheal_m #hpheal_a
if #mark <> 1
    goto #mark
end_if
send {num_4} #gcd
readmem #hpDD_m #adress_maxHP_DD D
readmem #hpDD_a #adress_actHP_DD D
set #mark 0
call hpdd_check #hpDD_m #hpDD_a
if #mark <> 1
    goto #mark
end_if
while timer < 11000
    send {g}
    send {num_6} 2100
    send {num_0}
end_while
goto 0
:2
set timer
send {num_7} #gcd
send {num_8} #gcd
readmem #hpheal_m #adress_maxHP_Heal D
readmem #hpheal_a #adress_actHP_Heal D
set #mark 0
call hpheal_check #hpheal_m #hpheal_a
if #mark <> 2
    goto #mark
end_if
send {num_7} #gcd
readmem #hpDD_m #adress_maxHP_DD D
readmem #hpDD_a #adress_actHP_DD D
set #mark 0
call hpdd_check #hpDD_m #hpDD_a
if #mark <> 2
    goto #mark
end_if
send {num_7} #gcd
readmem #hpheal_m #adress_maxHP_Heal D
readmem #hpheal_a #adress_actHP_Heal D
set #mark 0
call hpheal_check #hpheal_m #hpheal_a
if #mark <> 2
    goto #mark
end_if
while timer < 11000
    send {g}
    send {num_9} 2100
    send {num_0}
end_while
goto 0
Proc hpdd_check #hpDD_m #hpDD_a
set #cs current_script
set #hp1 div(#hpDD_m 4) * 3
if #hp1 > #hpDD_a
   set #mark.#cs 1
end_if
end_proc
Proc hpheal_check #hpheal_m #hpheal_a
set #cs current_script
set #hp2 div(#hpheal_m 4) * 3
if #hp2 > #hpheal_a
   set #mark.#cs 2
end_if
end_proc
end_script



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

А и еще заметил, что в процедуре почему-то не изменяется переменная скрипта типа $
Код

Proc hpheal_check #hpheal_m #hpheal_a
set #cs current_script
set #hp2 div(#hpheal_m 4) * 3
if #hp2 > #hpheal_a
   set #mark.#cs 2   <-- вот тут если использовать $mark.#cs то в скрипте переменная $mark не изменяет значение.
end_if
end_proc


Из-за чего пришлось использовать цифровые метки для переходов в основном скрипте.
cirus
Цитата
<-- вот тут если использовать $mark.#cs то в скрипте переменная $mark не изменяет значение.

Походу баг.
Можно сделать так:
Код
if #hp2 > #hpheal_a
   set %a [1] "$mark"
   eval (set %a [1].#cs 2)
end_if
Alfer
Что-то не могу победить изменение переменной скрипта в процедуре.

Код полный

// перед запуском скрипта прописать макросы для лечения фокуса и лечимый объект выбрать в фокус.
set #base_adress 0x00e29d28 // базовый, где хранится адрес ячейки начала структуры чара.
set #offset_maxHP 0x26b0 // смещение для поиска максимального значения ХП выбранного окна
set #hanldewinheal 66202360 // указать хендл окна хилера
set #hanldewinDD 3939646 // указать хендл окна ДД
set #gcd 1500
:0
set workwindow #hanldewinheal
readmem #first_adress #base_adress D
set #adress_maxHP_Heal #first_adress + #offset_maxHP //вычисляем адрес максимального значения ХП Хилера
set #adress_actHP_Heal #adress_maxHP_Heal - 0x18 //вычисляем адрес актуального значения ХП Хиера
set workwindow #hanldewinDD
readmem #first_adress #base_adress D
set #adress_maxHP_DD #first_adress + #offset_maxHP //вычисляем адрес максимального значения ХП ДДшника
set #adress_actHP_DD #adress_maxHP_DD - 0x18 //вычисляем адрес актуального значения ХП ДДшника
set #mark 0
//wait 40s
call hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD
call hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal
goto #mark
goto 0
:1
set workwindow #hanldewinheal
send {num_4} #gcd
send {num_5} #gcd
set #mark 0
call hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD #mark
if #mark = 1
send {num_4} #gcd
set timer
call hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #mark
if #mark = 1
send {num_4} #gcd
call hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD #mark
if #mark = 1
log timer
while timer < 15000
send_down {DOWN}
send_up {DOWN}
send {num_6} 2100
send {num_0}
log timer
end_while
end_if
end_if
end_if
goto #mark
goto 0
:2
set workwindow #hanldewinheal
send {num_7} #gcd
send {num_8} #gcd
set #mark 0
call hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #mark
if #mark = 2
send {num_7} #gcd
set timer
call hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD #mark
if #mark = 2
send {num_7} #gcd
call hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #mark
if #mark = 2
log timer
while timer < 15000
send_down {DOWN}
send_up {DOWN}
send {num_9} 2100
send {num_0}
log timer
end_while
end_if
end_if
end_if
goto #mark
goto 0
Proc hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD #mark
set #temp_workwindow workwindow
//set #cs current_script
set workwindow #hanldewinDD
readmem #hpDD_m #adress_maxHP_DD D
readmem #hpDD_a #adress_actHP_DD D
set #hp1 #hpDD_a * 100 / #hpDD_m
log #hp1
log #mark.1
if #hp1 < 75
set #mark.1 1
else
set #mark.1 0
end_if
log #mark.1
set workwindow #temp_workwindow
end_proc
Proc hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #mark
set #temp_workwindow workwindow
//set #cs current_script
set workwindow #hanldewinheal
readmem #hpheal_m #adress_maxHP_Heal D
readmem #hpheal_a #adress_actHP_Heal D
set #hp2 #hpheal_a * 100 / #hpheal_m
log #hp2
if #hp2 < 75
set #mark.1 2
else
set #mark.1 0
end_if
set workwindow #temp_workwindow
end_proc
end_script


Проблема тут:
Код

set #mark 0
call hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD #mark
<...>
Proc hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #mark
     set #temp_workwindow workwindow
     set #cs current_script
     set workwindow #hanldewinheal
     readmem #hpheal_m #adress_maxHP_Heal D
     readmem #hpheal_a #adress_actHP_Heal D
     set #hp2 #hpheal_a * 100 / #hpheal_m
     log #hp2
     if #hp2 < 75
        set #mark.1 2       <---- Вот так выдается ошибка ( (7): Ошибка! Проверьте правильность скрипта! EAccessViolation Access violation at address 00547DF2 in module 'uopilot_b019.exe'. Read of address 00000040
set logging #mark.1)
     else
        set #mark.#cs 0    <---- А вот так переменная #mark в основном скрипте не меняется.
     end_if
     set workwindow #temp_workwindow
end_proc
Alfer
и еще вопросик.

Код

if #mark = 1
   send {num_4} #gcd
   set timer
   call hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #mark    <--- на этом шаге меняется переменная #mark по которой мы попали в тело Ифа и
    // условие для попадания перестает выполняться.
   if #mark = 1
      send {num_4} #gcd
      call hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD #mark
      if #mark = 1
         log timer
         while timer < 15000
         send_down {DOWN}
         send_up {DOWN}
         send {num_6} 2100
         send {num_0}
         log timer
         end_while
      end_if
   end_if
end_if


Меня выбросит из цикла ? или тело будет выполняться до конца и только потом будет еще раз проверяться условие попадания в тело ?
Alfer
Пока что получилось победить через Свитч.
По не наагришь толпу мобов(10+) на Хила и на ДД работает очень даже хорошо.

Код

Код

// перед запуском скрипта прописать макросы для лечения фокуса и лечимый объект выбрать в фокус.
set #base_adress 0x00e29d28 // базовый, где хранится адрес ячейки начала структуры чара.
set #offset_maxHP 0x26b0 // смещение для поиска максимального значения ХП выбранного окна
set #hanldewinheal 66202360  // указать хендл окна хилера
set #hanldewinDD 3939646 // указать хендл окна ДД
set #gcd 1500
:0
set #mark 0
set #part_hp_heal 100
set #part_hp_dd 100
set workwindow #hanldewinheal
readmem #first_adress #base_adress D
set #adress_maxHP_Heal #first_adress + #offset_maxHP //вычисляем адрес максимального значения ХП Хилера
set #adress_actHP_Heal #adress_maxHP_Heal - 0x18 //вычисляем адрес актуального значения ХП Хиера
set workwindow #hanldewinDD
readmem #first_adress #base_adress D
set #adress_maxHP_DD #first_adress + #offset_maxHP //вычисляем адрес максимального значения ХП ДДшника
set #adress_actHP_DD #adress_maxHP_DD - 0x18 //вычисляем адрес актуального значения ХП ДДшника
call hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD #part_hp_dd
call hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #part_hp_heal
set #heal_mark 0
set #heal_mark $hpdd_check + $hpheal_check
//log #heal_mark
switch #heal_mark
case 0:
  goto 0
case 1:
:heal_DD
set workwindow #hanldewinheal
send {num_4} #gcd
set timer
send {num_5} #gcd
call hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD #part_hp_dd
if $hpdd_check = 1
   send {num_4} #gcd
   call hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #part_hp_heal
   if $hpheal_check = 2
      goto heal_heal
   end_if
   send {num_4} #gcd
   call hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD #part_hp_dd
   if $hpdd_check = 1
      log timer
      while timer < 9000
           send_down {DOWN}
           send_up {DOWN}
           send {num_6} 2100
           send {num_0}
           log timer
      end_while
   else
   goto 0
   end_if
end_if
goto 0
case 2:
:heal_heal
set workwindow #hanldewinheal
send {num_7} #gcd
set timer
send {num_8} #gcd
call hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #part_hp_heal
if $hpheal_check = 2
   send {num_7} #gcd
   call hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD #part_hp_dd
   if $hpdd_check = 1
      goto heal_dd
   end_if
   send {num_7} #gcd
   call hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #part_hp_heal
   if $hpheal_check = 2
       log timer
          while timer < 9000
               send_down {DOWN}
               send_up {DOWN}
               send {num_9} 2100
               send {num_0}
               log timer
         end_while
   end_if
end_if
goto 0
case 3:                    //требует долаботки для отхила двух целей одновременно
    set #temp #part_hp_dd / #part_hp_heal
    if #temp < 1
        goto heal_dd
    else
        goto heal_heal
    end_if
end_switch
Proc hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD #part_hp_dd
     set #temp_workwindow workwindow
     set #cs current_script
     set workwindow #hanldewinDD
     readmem #hpDD_m #adress_maxHP_DD D
     readmem #hpDD_a #adress_actHP_DD D
     set #hp1 #hpDD_a * 100 / #hpDD_m
     if #hp1 < 75
        set $result 1
     else
        set $result 0
     end_if
     set #part_hp_dd.#cs #hp1
     set workwindow #temp_workwindow
end_proc
Proc hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #part_hp_heal
     set #temp_workwindow workwindow
     set #cs current_script
     set workwindow #hanldewinheal
     readmem #hpheal_m #adress_maxHP_Heal D
     readmem #hpheal_a #adress_actHP_Heal D
     set #hp2 #hpheal_a * 100 / #hpheal_m
     if #hp2 < 75
        set $result 2
     else
        set $result 0
     end_if
     set #part_hp_heal.#cs #hp2
     set workwindow #temp_workwindow
end_proc
end_script

cirus
Сколько времени хил откатывается?
Цитата
требует долаботки для отхила двух целей одновременно

Зачем делить хп, если можно просто их сравнить?

Когда вижу goto аж плохо становится. Гораздо понятнее, если использовать gosub.
Alfer
Цитата
Когда вижу goto аж плохо становится. Гораздо понятнее, если использовать gosub.


Хде ж вы раньше были ?! wink.gif Перечитал мануал и особенно понравилось: "В отличии от goto имеет оператор для возврата обратно, в место перенаправления - return. "

спс за подсказку при беглом изучении функционала не обратил внимания на gosub. Буду переделывать вроде как это должно решить одну из моих проблем.

Цитата
Сколько времени хил откатывается?


6 макросов по 3 спела на юнита(1 юнит - Сам хил, 2 юнит - ДД(фокус или партимембер с номером 1-5, пока - фокус))

Я делаю для связки Фурик+рДру

Спелы

Lifbloom - instant cast, 1,5sec global cooldown 7 sec висит на таргете, 3 раза стакается на таргете с каждым след разм отхил больше.
Rejuv - instant cast, 1,5sec global cooldown, 12 sec висит на таргете не стакается

Regrowth - 2 sec cast, отхил после каста и висит на таргете 21 sec.

Формально логика отхила такая


смотрим на хп ДД и Хила пока чей-то не будет меньше 75%
переходим к отхилу того у кого меньше 75%
Lifbloom
Rejuv
запускаем таймер
смотрим хп если больше 75% выходим к мониторингу обоих ХП иначе дальше
Lifbloom
смотрим на ХП второго чара если у него меньше 75% переходим к его отхилу по такой же логике иначе дальше
Lifbloom
смотрим хп если больше 75% выходим к мониторингу обоих ХП иначе дальше
Пока таймер меньше 11 сек сбрасываем фоллоу шажочком назад и кастуем Regrowth используем макрос "преследовать фокус"
смотрим на ХП второго чара если у него меньше 75% переходим к его отхилу иначе дальше
всё.

Цитата
Зачем делить хп, если можно просто их сравнить?


А я их делением и сравниваю. Так как пилот не умеет работать с нецелыми числами, а те меременные у меня могут быть в диапазоне 0-100 - то если разделю меньшее на большее получу 0, а если одинаково или большее на меньшее - получу 1. И, кстати, я сравниваю остаток ХП в процентах. На мой взгляд просто и быстро работает.
DarkMaster
хп в процентах имхо правильно. По остальному коду глаза пока ломать не стал, избавляйтесь от гото smile.gif
cirus
Цитата
set #gcd 1500
send {num_4} #gcd
set timer
send {num_5} #gcd

Это останавливает скрипт на 3 секунды. Если в это время потребуется хил для другого перса?
Обычно делается через таймер. Т. е. хп проверяется всё время, а хил используется только если он уже откатился.
Код
set linedelay 10
set #time 0

while 1 = 1
    log Проверяем хп
    if #time < timer and 1 = 1   // вместо 1 = 1 проверять хп (нужен хил или нет)
    log Хил
    set #time timer + 1500
    end_if
end_while

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


Не знаю знакомы ли Вы с механикой вов, но есть такое понятие как Глобал Кулдаун, который запускается после использования 95% скилов в игре и равен от 1 до 1.5 секунды в зависимости от параметра Haste в это время что-либо другое кастовать нельзя другой скилл просто не сможет использоваться. А вот читать в это время хп - очень может быть. Собственно подумываю вынести вычисление процента ХП в отдельный скрипт и передавать в первый готовое значение, чтобы каждый раз не дергаться в процедуру проверки ХП
cirus
Цитата
Не знаю знакомы ли Вы с механикой вов

Не играл.
Цитата
Собственно подумываю вынести вычисление процента ХП в отдельный скрипт и передавать в первый готовое значение, чтобы каждый раз не дергаться в процедуру проверки ХП

Как по мне, то в большинстве случаев проще делать в одном скрипте.
DarkMaster
Цитата
Не знаю знакомы ли Вы с механикой вов, но есть такое понятие как Глобал Кулдаун, который запускается после использования 95% скилов в игре и равен от 1 до 1.5 секунды в зависимости от параметра Haste в это время что-либо другое кастовать нельзя другой скилл просто не сможет использоваться. А вот читать в это время хп - очень может быть. Собственно подумываю вынести вычисление процента ХП в отдельный скрипт и передавать в первый готовое значение, чтобы каждый раз не дергаться в процедуру проверки ХП

Это бывает актуально, т.к. создает своего рода API при работе скриптов. Это бывает очень актуально, когда вычисления занимают значимый промежуток времени и мы можем использовать значения не дожидаясь выполнения полного цикла обновления значений. В данном случае у меня есть некоторые сомнения по поводу целесообразности, т.к. все отрабатывать должно практически мгновенно.
Alfer
Вот так заработало так как надо.

Скрипт

Код

// перед запуском скрипта прописать макросы для лечения фокуса и лечимый объект выбрать в фокус.
set #base_adress 0x00e29d28 // базовый, где хранится адрес ячейки начала структуры чара.
set #offset_maxHP 0x26b0 // смещение для поиска максимального значения ХП выбранного окна
set #hanldewinheal 1254942   // указать хендл окна хилера
set #hanldewinDD 26416278 // указать хендл окна ДД
set #gcd 1500
:0
set #part_hp_heal 100
set #part_hp_dd 100
set workwindow #hanldewinheal
readmem #first_adress #base_adress D
set #adress_maxHP_Heal #first_adress + #offset_maxHP //вычисляем адрес максимального значения ХП Хилера
set #adress_actHP_Heal #adress_maxHP_Heal - 0x18 //вычисляем адрес актуального значения ХП Хиера
set workwindow #hanldewinDD
readmem #first_adress #base_adress D
set #adress_maxHP_DD #first_adress + #offset_maxHP //вычисляем адрес максимального значения ХП ДДшника
set #adress_actHP_DD #adress_maxHP_DD - 0x18 //вычисляем адрес актуального значения ХП ДДшника
call hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD #part_hp_dd
call hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #part_hp_heal
set #heal_mark 2
if  (#part_hp_dd <= 75) or (#part_hp_heal <= 75)
    if #part_hp_dd < #part_hp_heal
       set #heal_mark 0
    else
       set #heal_mark 1
    end_if
end_if
switch #heal_mark
case 0:
    gosub Heal_D
    break
case 1:
    gosub Heal_H
    break
case 2:
    break
end_switch
goto 0
Proc hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD #part_hp_dd
     set #temp_workwindow workwindow
     set #cs current_script
     set workwindow #hanldewinDD
     readmem #hpDD_m #adress_maxHP_DD D
     readmem #hpDD_a #adress_actHP_DD D
     set #hp1 #hpDD_a * 100 / #hpDD_m
     set $result #hp1
     set #part_hp_dd.#cs #hp1
     set workwindow #temp_workwindow
end_proc
Proc hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #part_hp_heal
     set #temp_workwindow workwindow
     set #cs current_script
     set workwindow #hanldewinheal
     readmem #hpheal_m #adress_maxHP_Heal D
     readmem #hpheal_a #adress_actHP_Heal D
     set #hp2 #hpheal_a * 100 / #hpheal_m
     set $result #hp2
     set #part_hp_heal.#cs #hp2
     set workwindow #temp_workwindow
end_proc
end_script
:Heal_D
set workwindow #hanldewinheal
send {num_4} #gcd
set timer
send {num_5} #gcd
call hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD #part_hp_dd
if #part_hp_dd >= 75
    return
end_if
send {num_4} #gcd
call hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #part_hp_heal
if #part_hp_heal < 75
    gosub Heal_H
end_if
send {num_4} #gcd
call hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD #part_hp_dd
if #part_hp_dd >= 75
    return
end_if
call hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #part_hp_heal
if #part_hp_heal < 75
    gosub Heal_H
end_if
while timer < 9000
    send_down {DOWN}
    send_up {DOWN}
    send {num_6} 2100
    send {num_0}
    call hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD #part_hp_dd
    if #part_hp_dd >= 75
        return
    end_if
end_while
return
:Heal_H
set workwindow #hanldewinheal
send {num_7} #gcd
set timer
send {num_8} #gcd
call hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #part_hp_heal
if #part_hp_heal >= 75
    return
end_if
send {num_7} #gcd
call hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD #part_hp_dd
if #part_hp_dd < 75
    gosub Heal_D
end_if
send {num_7} #gcd
call hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #part_hp_heal
if #part_hp_heal >= 75
    return
end_if
call hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD #part_hp_dd
if #part_hp_dd < 75
    gosub Heal_D
end_if
while timer < 9000
    send_down {DOWN}
    send_up {DOWN}
    send {num_9} 2100
    send {num_0}
    call hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #part_hp_heal
    if #part_hp_heal >= 75
        return
    end_if
end_while
return



Теперь попытаюсь еще отследить прерывание каста при нанесении хилу дмг.
DarkMaster
Цитата
set #hanldewinheal 1254942 // указать хендл окна хилера
set #hanldewinDD 26416278 // указать хендл окна ДД

Хотите сделать красиво? Соберите все хендлы окон вова, и выедите через промпт запрос с никами чаров.
Alfer
Идея интересная, но была бы актуальна, если бы не нужно было настраивать макросы в самой игре. А плот не может работать а апи вов отправкой команд ? http://wowwiki.wikia.com/wiki/API чтобы макросы не нужно было писать, а всё сделать на уровне пилота указав ему только ники Хила и ДД, а дальше вытаскивать класс хила и уже на основании этого как-то управлять процессом. Кстати для ультимы у пилота есть "характеристики персонажа" а может можнго аналогично сделать для ВоВ через оффсеты ?
Alfer
Растащил по двум скриптам. Работает быстрее, но периодически возникает ошибка:
12:09:33 1 (autosaved_1.txt, 14): call - (14): Ошибка! Проверьте правильность скрипта! EThread Thread Error: Неверный дескриптор (6)
call hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #part_hp_heal

В этом скрипте:
Код

set #base_adress 0x00e29d28 // базовый, где хранится адрес ячейки начала структуры чара.
set #offset_maxHP 0x26b0 // смещение для поиска максимального значения ХП выбранного окна
set #hanldewinheal 3021128  // указать хендл окна хилера
set #hanldewinDD 5645786  // указать хендл окна ДД
:0
set workwindow #hanldewinheal
readmem #first_adress #base_adress D
set #adress_maxHP_Heal #first_adress + #offset_maxHP //вычисляем адрес максимального значения ХП Хилера
set #adress_actHP_Heal #adress_maxHP_Heal - 0x18 //вычисляем адрес актуального значения ХП Хиера
set workwindow #hanldewinDD
readmem #first_adress #base_adress D
set #adress_maxHP_DD #first_adress + #offset_maxHP //вычисляем адрес максимального значения ХП ДДшника
set #adress_actHP_DD #adress_maxHP_DD - 0x18 //вычисляем адрес актуального значения ХП ДДшника
call hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD #part_hp_dd
call hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #part_hp_heal
goto 0
Proc hpdd_check #hanldewinDD #adress_maxHP_DD #adress_actHP_DD #part_hp_dd
     set #temp_workwindow workwindow
     set #cs current_script
     set workwindow #hanldewinDD
     readmem #hpDD_m #adress_maxHP_DD D
     readmem #hpDD_a #adress_actHP_DD D
     set #hp1 #hpDD_a * 100 / #hpDD_m
     set $result #hp1
     set #part_hp_dd.#cs #hp1
     set workwindow #temp_workwindow
end_proc
Proc hpheal_check #hanldewinheal #adress_maxHP_Heal #adress_actHP_Heal #part_hp_heal
     set #temp_workwindow workwindow
     set #cs current_script
     set workwindow #hanldewinheal
     readmem #hpheal_m #adress_maxHP_Heal D
     readmem #hpheal_a #adress_actHP_Heal D
     set #hp2 #hpheal_a * 100 / #hpheal_m
     set $result #hp2
     set #part_hp_heal.#cs #hp2
     set workwindow #temp_workwindow
end_proc
end_script

междустрочный интервал 30мс.
Может какой-то одновременный доступ к переменным разными скриптами?
DarkMaster
Цитата
междустрочный интервал 30мс.

всегда работаю на нуле. Там где нужно сами проставьте вэйты.
Цитата
Может какой-то одновременный доступ к переменным разными скриптами?

Очень высока вероятность. Я бы все-таки свернул в один скрипт. У вас нет ресурсоемких действий чтобы получать приросты и не блокировать какими-то операциями основной скрипт. Прото задержку на ноль, выключить логирование, выключить слежение.
DarkMaster
Цитата
А плот не может работать а апи вов отправкой команд ? http://wowwiki.wikia.com/wiki/API чтобы макросы не нужно было писать, а всё сделать на уровне пилота указав ему только ники Хила и ДД, а дальше вытаскивать класс хила и уже на основании этого как-то управлять процессом. Кстати для ультимы у пилота есть "характеристики персонажа" а может можнго аналогично сделать для ВоВ через оффсеты ?

Как-то не заметил данный пост. Если еще актуально, то:
Для вызова данных функций необходимо вмешательство в процесс. Вообще можно - так все боты работают. По факту в данный момент - нет.
Касательно работы со переменными зарезервированными, как в ультиме - под ультиму уже был пост от кнайта "находите оффсеты - все добавлю". Разницы ультима это или вов никакой. Просто нужные оффсеты. Даже все переменные будут те же самые.
Cockney
Дать возможность резервировать пользовательские переменные. Это было бы лучшим выходом без засорения пилота 999 переменными к разным играм.

А я еще давно это предлогал, результатата только нет.
DarkMaster
что есть резервированная пользовательская переменная? На данный момент за переменными зарезеривроанными в пилоте стоят функции. Речь о том чтобы сделать прозрачной вызов цепочки указателей. Если по большому счету, то через call можно сделать сейчас тоже самое. Только это некоторое нагромождение.
Cockney
Тоже самое что ты и написал. При запуске пилота выполнять

set <varname> readmem() //функция
set <varname2> 100 //константа
set <varname2> 130 //переопределение константы

Можно прям в инишник и прибить формочку-редактор.
DarkMaster
ок. Допустим. Какие приемущества над call при таком варианте работы? До инишника нужно еще долезть, а тут все на поверхности. Может имеет смысл просто заставить call возвращать некоторое значение вместо себя, как обычную функцию?
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.
Русская версия Invision Power Board © 2001-2024 Invision Power Services, Inc.