//Скрипт осуществляет перемещение персонажа (стрелки вперед и поворот вправо-влево) по контрольным точкам в 3Д игре с видом от 3го лица
//координатная сетка: слева -X, cправа +X, сверху -Y, снизу +Y
//адреса в памяти программы тип hex; X,Y - координаты тип float
//$_Sx,$_Sy - координаты камеры от 3го лица
//$_Ax,$_Ay - текущие координаты персонажа
//$_Bx,$_By - координаты текущей контрольной точки
#ps2_keyboard
// отключить NumLock (Кликер с включенным глючит)
#include "float.cms" //подключение процедуры переводящей hex 4 байта во float 4 байта
#include "azimut.cms" //вызятие азимута
wait(1)
$_ms1g = 1.02 * 6684 / 360 //поворот (1.02 - поправочный коэф; 6684 - время в мс за которое персонаж повернется на 360 градусов)
EXECUTE("pid.exe") //получение PID игры и запись в Find_PID.ini(привязка по названию окна)
WAIT(2)
$_pid = INT(INIREAD("Find_PID.ini", "pid"))
$_addr = readmem($_pid, 0x102D19F0, 4) //не базовый адрес, но некоторое время начальный адрес здесь храниться
$_addrX = $_addr + 0x000003E0 //Х координаты перса в HEX
$_addrY = $_addr + 0x000003E4 //y
$_addrXs = $_addr + 0x00000950 //х координаты камеры от 3-го лица
$_addrYs = $_addr + 0x00000954 //у
$_a025 = RND(200,220) //время минимально возможной задержки
$_a1 = RND(1000,1100)
KEYDOWN(#TAB) //что бы можно было стрелками управлять персонажем
waitms($_a025)
KEYUP(#TAB)
waitms($_a025)
KEYDOWN(#TAB)
waitms($_a025)
KEYUP(#TAB)
waitms($_a025)
KEYDOWN(#UP) //сразу после загрузки (по адресу в памяти) координаты персонажа 0, после короткой пробежки сервер пересылает текущие координаты
waitms($_a025)
KEYUP(#UP)
waitms($_a01)
$_ks = TFCOUNT("loc.txt") + 1
FOR($_loc = 1, $_loc < $_ks, 2)
$kl = 1
$_Bx = INT(TFREAD("loc.txt", $_loc)) //чтение координат текущей контрольной точки
$_By = INT(TFREAD("loc.txt", ($_loc + 1)))
WHILE($kl = 1)
$_Ax = readmem($_pid, $_addrX, 4) //чтение координат текущей координаты перса
int_to_Float($_Ax)
$_Ax = int($float)
$_Ay = readmem($_pid, $_addrY, 4)
int_to_Float($_Ay)
$_Ay = int($float)
$_Sx = readmem($_pid, $_addrXs, 4) ////чтение координат камеры от 3го лица
int_to_Float($_Sx)
$_Sx = int($float)
$_Sy = readmem($_pid, $_addrYs, 4)
int_to_Float($_Sy)
$_Sy = int($float)
azimut($_Ax,$_Ay,$_Bx,$_By) //взятие азимута с текущей координаты перса на текущую контрольную точку
$_AzAB = $angle
$_Dab = $_Dt1t2 //дистанция до контрольной точки
azimut($_Sx,$_Sy,$_Ax,$_Ay) //взятие азимута с координаты камеры от 3го лица на текущуие координаты перса
$_AzSA = $angle
$_deltaAz = abs($_AzSA - $_AzAB) //дельта между азимутами
if (($_AzSA < $_AzAB) and ($_deltaAz < 180) //какой поворот ближе туда и повернет навычесленный угол
KEYDOWN(#RIGHT)
waitms(int(($_deltaAz) * $_ms1g))
KEYUP(#RIGHT)
END_IF
if (($_AzSA > $_AzAB) and ($_deltaAz < 180)
KEYDOWN(#LEFT)
waitms(int(($_deltaAz * $_ms1g))
KEYUP(#LEFT)
END_IF
if (($_AzSA > $_AzAB) and ($_deltaAz >= 180)
KEYDOWN(#RIGHT)
waitms(int((360 - $_deltaAz) * $_ms1g))
KEYUP(#RIGHT)
END_IF
if (($_AzSA < $_AzAB) and ($_deltaAz >= 180)
KEYDOWN(#LEFT)
waitms(int((360 - $_deltaAz) * $_ms1g))
KEYUP(#LEFT)
END_IF
IF ($_Dab > 50) //50 - минимальная дистанция до контрольной точки, после достижения которой можно получить новую
KEYDOWN(#UP)
waitms(int($_Dab / 0.14)) //(бег) 0.14 - скорость(точки в мс), при паспортной скорости перса в 129 (0.185-170?)
KEYUP(#UP)
$kl = 1
else
$kl = 0
end_if
waitms($_a1)
END_CYC
END_CYC
halt
Vint - автор идеи с расчетом азимута (с геометрией у меня не очень процедуру переписал чтоб понятней было)
SUB(azimut,$t1x,$t1y,$t2x,$t2y) //=============================================
$_Dt1t2 = DIST($t1x,$t1y,$t2x,$t2y)
$_Dt1az = DIST($t1x,$t1y,$t1x,$t2y)
$_Dt2az = DIST($t2x,$t2y,$t1x,$t2y)
if ($_Dt1t2 = 0) //на 0 делить нельзя, может кто предложит более изящную идею
$_Dt1t2 = 0,1
end_if
if ($_Dt1az = 0)
$_Dt1az = 0,1
end_if
$_DV = POW($_Dt1az, 2) + POW($_Dt1t2, 2) - POW($_Dt2az, 2)
$_DN = 2 * $_Dt1t2 * $_Dt1az
$beta = arccos($_DV / $_DN)
if (($t1x > $t2x) and ($t1y > $t2y))
$angle = 360 - $beta
end_if
if (($t1x <= $t2x) and ($t1y >= $t2y))
$angle = $beta
end_if
if (($t1x < $t2x) and ($t1y < $t2y))
$angle = 180 - $beta
end_if
if (($t1x > $t2x) and ($t1y < $t2y))
$angle = 180 + $beta
end_if
END_SUB
dramster - автор процедуры перевода HEX 4 байта во FLOAT 4 байта
//перевод числа в двоичную строку $BIN (строка выйдет длиной в 32бит)
SUB(dec_to_BIN, $DEC)
$BIN = ""
IF($DEC > 0) //если положительное
WHILE($DEC > 0)
$DEC = $DEC/2
IF($DEC > int($DEC))
$BIN = STRCONCAT("1", $BIN)
else
$BIN = STRCONCAT("0", $BIN)
END_IF
$DEC = int($DEC)
END_CYC
WHILE(STRLEN ($BIN) < 32) //4 байта
$BIN = STRCONCAT("0", $BIN)
END_CYC
ELSE //если отрицательное
$DEC = abs($DEC+1)
WHILE($DEC > 0)
$DEC = $DEC/2
IF($DEC > int($DEC))
$BIN = STRCONCAT("0", $BIN)
else
$BIN = STRCONCAT("1", $BIN)
END_IF
$DEC = int($DEC)
END_CYC
WHILE(STRLEN ($BIN) < 32) //4 байта
$BIN = STRCONCAT("1", $BIN)
END_CYC
END_IF
END_SUB
//перевод из двоичной строки в десятичное число $DEC
SUB(bin_to_DEC, $BIN_str)
$DEC = 0
IF(ARRSIZE ($arr) = 0)
$num_arr = 1
FOR($i=0,$i<32)
arrpush($arr, $num_arr)
$num_arr = $num_arr*2
END_CYC
END_IF
FOR($i=0,$i < STRLEN($BIN_str))
$DEC = $DEC + ($arr[$i]*int(STRCUT($BIN_str, STRLEN($BIN_str)-$i, 1)))
END_CYC
END_SUB
//перевод из целочисленного в дробное $float. целочисленное 4 байт - long (Signed int) от -2147483648 до 2147483647
SUB(int_to_Float, $int_in)
dec_to_BIN($int_in)
bin_to_DEC(STRCUT ($BIN,2, 8))
$exp = $DEC //экспонента в десятичном
bin_to_DEC(STRCUT ($BIN,10, 32))
$mant = $DEC //мантиса в десятичном
$float = POW(-1,int(STRCUT ($BIN,1,1))) * pow(2,$exp-127) * (1+($mant/POW(2,23)))
END_SUB
///////////////////////////////////////////////////////////////////////////////
//основной код
// int_to_Float(-979615744)
// print($float) // -5000
Скрипт записывающий в файл loc.txt координаты контрольных точек
//ALT - запись X,Y координат контрольной точки
//ESC - выход
#name "loc"
#ps2_keyboard
$_sp = 0
$_pid = 0
THREAD(T1, 0) //поток считывающий координаты из памяти процесса и записывающий их в файл loc.txt
#include "float.cms"
$_Ax = readmem($_pid, $_addrX, 4)
$_Ay = readmem($_pid, $_addrY, 4)
IF($_sp = 1)
int_to_Float($_Ax)
TFWRITE("loc.txt", int($float))
int_to_Float($_Ay)
TFWRITE("loc.txt", int($float))
$_sp = 0
END_IF
WAIT(1)
END_THREAD
THREAD(T2, 0) //поток обрабатывающий нажатие клавиш
IF(iskeydown(#ALT)=1)
$_sp = 1
END_IF
IF(iskeydown(#esc)=1)
halt
END_IF
waitms(200)
END_THREAD
EXECUTE("pid.exe") //получение PID и запись его в файл Find_PID.ini
WAIT(2)
$_pid = INT(INIREAD("Find_PID.ini", "pid"))
$_addr = readmem($_pid, 0x102D19F0, 4)
$_addrX = $_addr + 0x000003E0
$_addrY = $_addr + 0x000003E4
SETTHREAD (T1, 1)
SETTHREAD (T2, 1)
wait(600000)
Поиск Базового Адреса осуществлен в Cheat Engine. Средствами Кликера до БА добраться не смог, нашел адрес в памяти где указатель на начало структуры некоторое время храниться.
PID.exe сделан в AutoIT