Вопросы по созданию КЛЕО-скриптов 2
|
|
Den_spb | Дата: Вторник, 25.06.2013, 23:56 | Сообщение # 331 |
![Den_spb](/avatar/99/577490.jpg) Создатель сайта
Группа: Администраторы
Сообщений: 1603
Статус: Offline
| Цитата (Vital) То есть, если я использую такой цикл, то надо подсчитать все повторения и умножить их на кол-во опкодов, правильно ли я понял? Грубо говоря - да, хотя такой способ определения производительности является приблизительным, т.к. для одних опкодов требуется выполнить меньшее количество операций кода exe, для других - большее.
Цитата (Vital) Как рассчитать координаты пикапа через память? 1) Получаем адрес структуры N-пикапа по формуле: начало блока пикапов + N * размер структуры пикапа. N здесь меняется от 0 до 619. 2) Читаем в 3 переменные смещения, по которым записаны координаты пикапа: +16, +18, +20. Размер чтения 2 байта, т.к. это целые двухбайтовые числа (word). 3) Переводим двухбайтовые целые (word) в четырехбайтовые целые (dword), затем переводим их в дробные (float) и делим на 8.0. Вот как это делает скрипт animtrain c координатами точек ж/д путей, которые тоже хранятся в памяти в формате "word * 8": Код 0085: 9@ = 0_CurrentPointAdress // (int) 0A8E: 10@ = 0_CurrentPointAdress + 2 // int Y NPoint 0A8E: 11@ = 0_CurrentPointAdre@ss + 4 // int Z NPoint // записали адреса смещений в 9@, 10@, 11@. for 31@ = 0 to 2 // применяем цикл с тремя повторениями (для переменных 9@, 10@, 11@) 0A8D: 9@(31@,3i) = read_memory 9@(31@,3i) size 2 virtual_protect 0 // читаем значения, записанные по смещениям if // переводим word в dword 9@(31@,3i) >= 0x8000 // negative word then 9@(31@,3i) += 0xFFFF0000 // convert to negative dword end 0093: 9@(31@,3f) = integer 9@(31@,3i) to_float // переводим dword в float 9@(31@,3f) /= 8.0 end // теперь координаты точки записаны в 9@, 10@, 11@ Зачем применяется такой способ хранения координат? Таким образом экономится память игры, т.к. на каждую координату расходуется 2 байта (word) вместо четырёх (float). Помимо координат пикапов и точек ж/д путей в таком формате хранятся координаты путей машин и некоторые другие координаты.
Цитата (Vital) Спасибо за ответы. Я порой думаю, что выгляжу для вас как полный нуб, который только достаёт вопросами... У тебя нормальные вопросы. Видно, что уже неплохо разбираешься в игре и скриптинге.
Цитата (DK22Pac) В ексе есть готовая функция, которая возвращает координаты пикапа (на входе - то ли сам пикап, то ли индекс). Наверное эта:Код .text:004549A0 ; RwV3D *__thiscall CPickup__getPickupCoords(CPickup *this, RwV3D *coords)
|
|
| |
Vital | Дата: Среда, 26.06.2013, 13:05 | Сообщение # 332 |
Группа: Проверенные
Сообщений: 206
Статус: Offline
| Den_spb, DK22Pac, спасибо за ответы и разъяснение. Способ перевода мне кажется необычным, но довольно сложным, хотелось бы разобраться с функцией. Здесь, как я понимаю, надо использовать Код 0AA7: call_function getPickupCoords num_params 3 pop 3 6@ 7@ 8@ 6@ 7@ 8@ Попробую таким образом, если получится. Хотелось бы разобраться с 0AA5, 0AA6, 0AA7 и 0АА8, так как я не очень понимаю разницу, потому что не занимался программированием на высоком уровне, только то, что в школе творили в Pascal, и всё. Не могли ли вы объяснить как-нибудь действие этих опкодов? Насколько я понял, 0АА7 работает подобно 0АВ1 (scm-функция), только при этом надо ещё освобождать память.
SCRIPTER
|
|
| |
Vital | Дата: Среда, 26.06.2013, 15:45 | Сообщение # 333 |
Группа: Проверенные
Сообщений: 206
Статус: Offline
| Ура! Спасибо всем вам за подсказки, советы и ответы! Скрипт практически моей мечты создан и вполне неплохо работает! Единственное, что я не знаю, так это то, будет ли скрипт работать, если оружия будет слишком много? Потому что постоянно идёт создание корон и проекций. Суть в том, что вокруг оружия теперь будет корона, а на земле - проекция, и так для каждого пикапа оружия. Выглядит красиво, я всем доволен. Вот весь код: http://pastebin.com/UCGBj3qg Это очень для меня здорово. Я добавил систему настройки через .ini файл, так что пользователь может как угодно настроить значение как короны, так и проекции. Можно изменить использование того или иного эффекта (вкл/выкл), а также его цвет. Если файл не найден, будут использованы стандартные установки. Вот содержимое файла .ini
Код [SETT];General Settings usecor = 1 usepar = 1
[CORONA];Circle around weapon R = 200 G = 0 B = 0
[PARTICLE];Light on the ground R = 0 G = 0 B = 200 Ещё раз спасибо за всё! Получилось красиво, если ещё необходима доработка, я сначала улучшу скрипт, а затем только выложу его. Возможно, сделаю видео-разбор всего кода скрипта в рамках серии "SB: Мои примеры", обязательно упомянув вашу помощь.
SCRIPTER
Сообщение отредактировал Vital - Среда, 26.06.2013, 15:47 |
|
| |
DK22Pac | Дата: Среда, 26.06.2013, 20:57 | Сообщение # 334 |
![DK22Pac](/avatar/59/872075.gif) $player_actor
Группа: Проверенные
Сообщений: 559
Статус: Offline
| Vital, при работе с функциями в CLEO нельзя получить больше одного возвращвемого параметра. Эта функция работает по-другому. В нее передается указатель на вектор (3 флоата). Допустим, ты передаешь указатель на переменную 0@. Тогда результат запишется в переменные 0@, 1@, 2@. Код 0AA5: call 0x4549A0 {указатель на 0@ (CLEO4)} 0@v {адрес структуры пикапа} 1@ Структуры можно перебирать так for 1@ = (адрес первой структуры) to (адрес последней структуры) step (размер одной структуры) Почитай про цикл for в справке. О 0AA5-0AA8 рассказывать не буду. Можно ведь было поискать, до того как задавать вопрос? На SB форумах это уже столько раз "разжевали"... И не знаю, почему ты это к программированию привязываешь. Я - не программист, и до знакомства с SB я о программировании ничего не знал. Даже паскаль. В наше время же уже есть все, чтобы разобраться в этом, даже не залезая в дебри каких-либо языков программирования. Я знаю как минимум 5 сайтов, где есть куча примеров по работе с паматью. С другой стороны, что тебе мешает разобраться в основах (только в основах) программирования? Только "вьехать" в указатели и функции, - и будешь щелкать эти вызовы.
Сообщение отредактировал DK22Pac - Среда, 26.06.2013, 21:33 |
|
| |
Vital | Дата: Среда, 26.06.2013, 21:30 | Сообщение # 335 |
Группа: Проверенные
Сообщений: 206
Статус: Offline
| DK22Pac, про параметр step в for я слышал, помню о нём как раз из справки. Эти опкоды, пожалуй, действительно поищу на форумах, а то смотрел только в справке. Я о программировании говорю, потому что у меня склад ума, так сказать, сложно переваривает понятия вроде тех, что используются далее, в более сложных местах. У меня больше образное мышление, вот как я представил себе адреса памяти в виде деревьев, а смещения в виде ветвей, так стало легче воспринимать, а вот функции и методы, к примеру... В общем, я вас напрягать этим не буду, вы и так уже много помогали, постараюсь сам разобраться. Единственный нюанс: как понимать тип вектор? В SA я его не встречал ни разу, только координаты, тип vector я замечал только в GTA IV. Хотя, если не ошибаюсь, сам движок RenderWare написан на языке из семьи C, так что методы создания игр похожие должны быть, но как получить вектор из трёх точек координат в SA...
SCRIPTER
|
|
| |
Den_spb | Дата: Четверг, 27.06.2013, 00:04 | Сообщение # 336 |
![Den_spb](/avatar/99/577490.jpg) Создатель сайта
Группа: Администраторы
Сообщений: 1603
Статус: Offline
| Цитата (Vital) Единственный нюанс: как понимать тип вектор? Вектор - три координаты (три числа float), записанные в памяти последовательно (друг за другом). Например, если адрес вектора равен N, то адрес координаты X - N, координаты Y - N+4, координаты Z - N+8. Можно записать координаты в 3 последовательные переменные, например 0@ 1@ 2@, тогда адрес вектора - адрес первой переменной (адрес локальной переменной вычисляется опкодом 0AC7: 0@ = var 0@ offset ) Цитата (Vital) Эти опкоды, пожалуй, действительно поищу на форумах, а то смотрел только в справке. Про опкоды 0AA5-0AA8 есть информация тут: http://sannybuilder.com/forums/viewtopic.php?pid=22917#p22917
|
|
| |
Vital | Дата: Четверг, 27.06.2013, 15:22 | Сообщение # 337 |
Группа: Проверенные
Сообщений: 206
Статус: Offline
| Den_spb, DK22Pac, спасибо за совет насчёт форума, попробую изучать. Есть маленький прогресс: Код // $PLAYER_ACTOR $PLAYER_GROUP $ONMISSION {$CLEO} 0000: while true //1 wait 0 if //2 player.Defined(0) then if //3 not actor.Dead($PLAYER_ACTOR) then if //4 0AB0: key_pressed 0xDB then 0ACA: show_text_box "Game speed is decreased" 0AA5: call 0x00438FC0 num_params 0 pop 0 wait 400 else if //5 0AB0: key_pressed 0xDD then 0ACA: show_text_box "Game speed is increased" 0AA5: call 0x00438F90 num_params 0 pop 0 wait 400 end //5 end //4 end //3 end //2 end //1
Первая моя работа с 0AA5. Кстати, адреса функций, кроме GTAModding, можно найти, я так понял, только в IDA, открыв gtasa.exe? А есть ещё программы для просмотра строения .exe? P.S. Нашёл на форумах SB список функций, вопрос, по сути, может быть снят, но на всякий случай всё же оставлю его в силе.
SCRIPTER
Сообщение отредактировал Vital - Четверг, 27.06.2013, 15:32 |
|
| |
Den_spb | Дата: Суббота, 29.06.2013, 13:43 | Сообщение # 338 |
![Den_spb](/avatar/99/577490.jpg) Создатель сайта
Группа: Администраторы
Сообщений: 1603
Статус: Offline
| Цитата (Vital) А есть ещё программы для просмотра строения .exe? Вроде есть, но IDA самая популярная, т.к. в ней больше всего возможностей и опций.
Цитата (Vital) Кстати, адреса функций, кроме GTAModding, можно найти, я так понял, только в IDA, открыв gtasa.exe? В IDA нужно открывать не gta_sa.exe, а базу gta_sa_idb, скачать которую можно здесь: http://public.sannybuilder.com/gtasa_exe_idb/ Чем позднее дата в названии версии базы - тем свежее версия, однако для открытия более поздних версий баз потребуется и более свежая версия IDA. Список всех функций gta_sa.exe в IDA отображается на вкладке Functions. P.S. Кстати, с помощью опкодов 0AA5 - 0AA8 можно вызывать не только функции exe. Можно, например, вызвать функцию, код которой прописан в теле клео-скрипта. Как это делается можно посмотреть тут: http://sannybuilder.com/forums/viewtopic.php?id=1068
|
|
| |
Vital | Дата: Суббота, 06.07.2013, 00:15 | Сообщение # 339 |
Группа: Проверенные
Сообщений: 206
Статус: Offline
| Есть маленький вопросик: ничего не случится плохого, если не выключать text_draw? То есть, если есть в цикле enable_text_draw 1, и значение 0 не выставляется после использования этой команды, ничего не должно быть негативного с игрой?
SCRIPTER
|
|
| |
Den_spb | Дата: Суббота, 06.07.2013, 22:36 | Сообщение # 340 |
![Den_spb](/avatar/99/577490.jpg) Создатель сайта
Группа: Администраторы
Сообщений: 1603
Статус: Offline
| По своему опыту могу сказать, что в цикле, выводящем на экран текстуры или текст необходимо и достаточно написать только команду enable_text_draw 1 - скрипты нормально работают.
|
|
| |
Vital | Дата: Суббота, 06.07.2013, 22:53 | Сообщение # 341 |
Группа: Проверенные
Сообщений: 206
Статус: Offline
| Den_spb, спасибо за ответ. У меня тоже не было пока никаких ошибок с этим, я лишь думал перестраховаться, так как в одно время могут сработать несколько скриптов, использующих вывод текста/текстур, и если где-то (неважно, мои ли это скрипты или чужие) будет значение 0, то возможна ситуация, когда в одном скрипте флаг включился, а затем из-за другого отключился ещё до появления текстуры, и произойдёт вылет. В принципе, я, скорее всего, недооцениваю возможности компьютера, но всё же такие опасения у меня возникли не так давно.
SCRIPTER
|
|
| |
Den_spb | Дата: Воскресенье, 07.07.2013, 03:22 | Сообщение # 342 |
![Den_spb](/avatar/99/577490.jpg) Создатель сайта
Группа: Администраторы
Сообщений: 1603
Статус: Offline
| Цитата (Vital) то возможна ситуация, когда в одном скрипте флаг включился, а затем из-за другого отключился ещё до появления текстуры, и произойдёт вылет. Такого не может быть. В любой момент времени может выполняться только один процесс движка: например, отрисовка на экране, обработчик скриптов и т.д. В свою очередь, обработчик скриптов выполняет скрипты по очереди, т.е. несколько скриптов тоже одновременно выполняться не могут. Причём код текущего скрипта выполняется от одной команды wait до следующей команды wait - после чего скрипт опять становится в очередь.
|
|
| |
Vital | Дата: Воскресенье, 07.07.2013, 14:24 | Сообщение # 343 |
Группа: Проверенные
Сообщений: 206
Статус: Offline
| Den_spb, не очень понятно, вот я создал два скрипта, каждый из которых запускается по нажатии клавиши 3. Оба работают одновременно, то есть, в одном есть проигрывание звука и выдача игроку 100 долларов, в другом - подкидывание игрока вверх и изъятие у него 50 долларов. Причём работают странно: иногда даётся 100, иногда - 50 долларов (+100 в одном скрипте, -50 в другом, останется, по логике, +50), но всегда идёт звук и всегда подкидывание игрока... Ощущение, что некоторые опкоды просто пропускаются... Но иногда взаимно дополняют действие друг друга.
SCRIPTER
|
|
| |
Den_spb | Дата: Воскресенье, 07.07.2013, 16:30 | Сообщение # 344 |
![Den_spb](/avatar/99/577490.jpg) Создатель сайта
Группа: Администраторы
Сообщений: 1603
Статус: Offline
| Видимо твои скрипты в разных случаях выполняются разное количество раз, потому что время удержания клавиши было различным. Если скрипты были выполнены один раз, то игроку даётся 1*(100-50) = 50$, а если два раза, то сумма составит 2*(100-50)=100$. Чтобы код при нажатии клавиши выполнялся только один раз, необходимо добавлять цикл, который не допустит повторения действия до тех пор, пока клавиша не будет отпущена и нажата повторно:Код {$CLEO} wait 0 while true if 0AB0: key_pressed 0x73 then // действия, которые должны быть выполнены один раз при одном нажатии на кнопку repeat wait 0 until 8AB0: not key_pressed 0x73 else wait 0 end end
|
|
| |
Vital | Дата: Воскресенье, 07.07.2013, 17:04 | Сообщение # 345 |
Группа: Проверенные
Сообщений: 206
Статус: Offline
| Den_spb, но всё-таки взаимное влияние двух скриптов друг на друга возможно? С помощью velocity, кстати, хорошо видно, один раз нажата клавиша, или её держат, так как подкидывание идёт не плавно, а с дёрганьем. При одинарном нажатии даётся как раз 100-50 = 50. Значит, всё же возможно случайное совпадение опкодов, при котором, к примеру, какой-то флаг сбрасывается сразу после того, как в другом скрипте он был включён? Добавлено (07.07.2013, 17:04) --------------------------------------------- Den_spb, кстати, по поводу 8 в условиях: у меня в одном случае не удалось сделать обратное условие, это опкод 0818: actor $PLAYER_ACTOR in_air Я пробовал 8818, но действие могло выполняться в воздухе...
SCRIPTER
|
|
| |