Вопросы по созданию КЛЕО-скриптов 2
|
|
DK22Pac | Дата: Среда, 12.06.2013, 00:42 | Сообщение # 316 |
$player_actor
Группа: Проверенные
Сообщений: 559
Статус: Offline
| ILYALION, если не ошибаюсь, у каждого из наследователей CVehicle есть метод BlowUp. Туда и смотри. Добавлено (12.06.2013, 00:42) --------------------------------------------- ILYALION, попробуй так применять код ко всему поезду. Код {$CLEO}
{$I inloop} {$I forallcars}
0A97: 0@ = car veh struct 0A8E: 1@ = 0@ + 0x590 0A8D: 2@ = read_memory 1@ size 1 virtual_protect 0 0A8E: 1@ = 0@ + 0x5B8 0A8D: 3@ = read_memory 1@ size 1 virtual_protect 0 if and 2@ == 6 // if(train->m_bVehicleType == VEHICLETYPE_TRAIN && (train->m_bFlags & TRAINFLAG_IS_FRONT_CARRIAGE)) 08B7: test 3@ bit 3 then // // код для этого вагона // // for(i = train->m_pNextCarriage; i; i = i->m_pNextCarriage) 0A8E: 1@ = 0@ + 0x5B4 0A8D: 1@ = read_memory 1@ size 4 virtual_protect 0 while 1@ <> 0 // // код для других вагонов, 0@ - структура главного вагона, 1@ - структура этого вагона // 0A8E: 1@ = 1@ + 0x5B4 0A8D: 1@ = read_memory 1@ size 4 virtual_protect 0 end end
{$I for_end} {$I end}
|
|
| |
Den_spb | Дата: Среда, 12.06.2013, 17:12 | Сообщение # 317 |
Создатель сайта
Группа: Администраторы
Сообщений: 1603
Статус: Offline
| ILYALION, 1.В цикле сведения поезда с рельсов ты двигаешься от найденного вагона к концу состава (0x5D4 - смещение структуры вагона, по которому записан адрес структуры следующего вагона). Чтобы свести с рельсов весь поезд, нужно сначала найти нулевой вагон, а затем уже применять цикл ко всем вагонам этого поезда. Вагон является нулевым, если предыдущие вагоны отсутствуют, т.е. по смещению "предыдущий вагон" (0x5D0) записан ноль. Вот как ищет поезда скрипт animtrain:Код while true 32@ = 0 wait 5 if not player.Defined($PLAYER_CHAR) then continue end
if 0AE2: 0_Train = random_vehicle_near_point 0.0 0.0 0.0 in_radius 6000.0 find_next 0 pass_wrecked 1 //IF and SET then repeat 0A97: 0_CarriageStruct = car 0_Train struct 0A8E: 31@ = 0_CarriageStruct + 1424 // int 0A8D: 31@ = read_memory 31@ size 1 virtual_protect 0 if 31@ == 6 then 0_CarriageStruct += 0x5D0 0A8D: 0_CarriageStruct = read_memory 0_CarriageStruct size 4 virtual_protect 0 if 0_CarriageStruct == 0 // предыдущий вагон отсутствует (данный вагон является нулевым) then if 8981: not train 0_Train wrecked then gosub @_CTrain_process_control end end end until 8AE2: not 0_Train = random_vehicle_near_point 0.0 0.0 0.0 in_radius 6000.0 find_next 1 pass_wrecked 1 //IF and SET end end В результате скрипт сразу находит нулевые вагоны всех существующих поездов. 2.Колёса у сошедшего поезда продолжают крутиться потому, что animtrain проверяет на схождение только нулевой вагон каждого поезда. Чтобы колёса не крутились нужно либо сводить с рельсов весь поезд, либо (если какие-то вагоны остаются на рельсах) обнулять значения 0x5D4 в последнем уцелевшем вагоне и 0x5D0 в первом сошедшем с рельсов вагоне. 3.FPS падает возможно из-за того, что увеличивается время отработки скрипта animtrain. Это можно исправить после выполнения п.2. Vital, цикл здесь выполняется столько раз, сколько существует вагонов в поезде, т.е. не более 20, т.е. исполняются 12 х 20 = 240 опкодов, что не занимает много времени. Поэтому прерывать исполнение скрипта командой wait здесь не нужно.
|
|
| |
ILYALION | Дата: Суббота, 15.06.2013, 20:16 | Сообщение # 318 |
Группа: Проверенные
Сообщений: 325
Статус: Offline
| Den_spb, для нахождения первого вагона поезда я использовал следующий код:Код while true 0A97: 7@ = car 6@ struct 7@ += 0x5D0 0A8D: 7@ = read_memory 7@ size 4 virtual_protect 0 if 7@ == 0 then break else 0085: 6@ = 7@ // (int) end end Но происходит вылет. Почему?
|
|
| |
Den_spb | Дата: Воскресенье, 16.06.2013, 01:07 | Сообщение # 319 |
Создатель сайта
Группа: Администраторы
Сообщений: 1603
Статус: Offline
| Вылетит на второй раз выполнения цикла во время исполнения 0A97: в 6@ должен быть записан хэндл, а вместо него будет подан адрес структуры. Поэтому 0A97 надо вынести из цикла: Код 0A97: 6@ = car 6@ struct while 6@ <> 0 0085: 7@ = 6@ // (int) 6@ += 0x5D0 0A8D: 6@ = read_memory 6@ size 4 virtual_protect 0 end // Теперь в 7@ записан адрес структуры 0 вагона Вообще хэндлы используются только в скриптах, в exe применяются только адреса структур.
|
|
| |
ILYALION | Дата: Воскресенье, 16.06.2013, 12:31 | Сообщение # 320 |
Группа: Проверенные
Сообщений: 325
Статус: Offline
| Что означат данная запись? &0(30@,1i) Если изменить &0 или 1i изменится ли что-то?
|
|
| |
Den_spb | Дата: Воскресенье, 16.06.2013, 14:05 | Сообщение # 321 |
Создатель сайта
Группа: Администраторы
Сообщений: 1603
Статус: Offline
| Это старая технология чтения и записи памяти через массивы - она применялась до того, как появились специальные опкоды для чтения и записи памяти: 0A8C и 0A8D. В справке SB есть подробная статья на эту тему: Статьи - Опытным пользователям - Меняем игровую память через SCM (San Andreas). Перед изучением данной статьи надо вспомнить что такое массивы и как они реализуются в скриптах: Справка SB - Кодинг - Массивы.
|
|
| |
Vital | Дата: Воскресенье, 16.06.2013, 18:08 | Сообщение # 322 |
Группа: Проверенные
Сообщений: 206
Статус: Offline
| Кто-нибудь знает, сколько можно всего создать 2D объектов, если конкретнее - корон? И как можно реализовать рисование линий в 3D пространстве игры без применения create_M4_shoot (если возможно)?
SCRIPTER
|
|
| |
Den_spb | Дата: Воскресенье, 16.06.2013, 22:46 | Сообщение # 323 |
Создатель сайта
Группа: Администраторы
Сообщений: 1603
Статус: Offline
| Цитата (Vital) Кто-нибудь знает, сколько можно всего создать 2D объектов, если конкретнее - корон? 64 штуки http://gtamodding.ru/wiki/Адреса_Памяти_(SA)#CRegisteredCorona
|
|
| |
ILYALION | Дата: Понедельник, 17.06.2013, 08:28 | Сообщение # 324 |
Группа: Проверенные
Сообщений: 325
Статус: Offline
| На wiki есть это:Код CGlass (Осколки стекла)
Начало: 0xC3E058 Размер одного элемента: 112 байт CGlass +0x0 = [RwMatrix]Матрица поворота и позиции CGlass +0x60 = [dword]Время создания CGlass +0x6D = [byte]Флаг существования А как можно создать осколки стекла?
------------------------------------------------ Есть такой адрес:Код 0x05A0 | WORD pathPointID // Текущий номер точки маршрута (номер строчки в tracks, нумерация от нуля) А можно узнать координаты этой точки?
Сообщение отредактировал ILYALION - Понедельник, 17.06.2013, 09:50 |
|
| |
Den_spb | Дата: Понедельник, 17.06.2013, 22:15 | Сообщение # 325 |
Создатель сайта
Группа: Администраторы
Сообщений: 1603
Статус: Offline
| Цитата (ILYALION) А можно узнать координаты этой точки? Можно. Вот как это реализуется в скрипте animtrain: Код
0A8E: 0_TrainRoute = 0_CarriageStruct + 0x5C0 // int Читаем номер маршрута - он записан в структуре вагона по смещению 0x5C0 0A8D: 0_TrainRoute = read_memory 0_TrainRoute size 1 virtual_protect 0 // train route 0_TrainRoute *= 4 // далее вычисляем адрес массива структур точек данного маршрута
0A8E: 0_StartOfTracksNdatContent = 0_TrainRoute + 0xC38024 // _tracksDatContents // int 0A8D: 0_StartOfTracksNdatContent = read_memory 0_StartOfTracksNdatContent size 4 virtual_protect 0 // start of tracksN.dat content
0A8E: 0_CurrentPointAdress = 0_CarriageStruct + 0x5A0 // int Получаем номер текущей точки 0A8D: 0_CurrentPointAdress = read_memory 0_CurrentPointAdress size 2 virtual_protect 0 // current point of train 0_CurrentPointAdress *= 10 // умножаем на размер структуры точки - 10 байтов 005A: 0_CurrentPointAdress += 0_StartOfTracksNdatContent // прибавили смещение к началу массива - получили адрес текущей точки
0085: 6@ = 0_CurrentPointAdress // (int) 0A8E: 7@ = 0_CurrentPointAdress + 2 // int Y NPoint 0A8E: 8@ = 0_CurrentPointAdress + 4 // int Z NPoint
for 31@ = 0 to 2 0A8D: 6@(31@,3i) = read_memory 6@(31@,3i) size 2 virtual_protect 0 if 6@(31@,3i) >= 0x8000 // negative word then 6@(31@,3i) += 0xFFFF0000 // convert to negative dword end 0093: 6@(31@,3f) = integer 6@(31@,3i) to_float 6@(31@,3f) /= 8.0 end // координаты записаны в 6@, 7@, 8@
Цитата (ILYALION) А как можно создать осколки стекла? На адрес 0xC3E058 ссылаются 3 функции: 0x6FADF0, 0x6FC180, 0x6FC4D0 - возможно одна из них и предназначена для создания осколков. Надо экспериментировать.
|
|
| |
DK22Pac | Дата: Вторник, 18.06.2013, 04:42 | Сообщение # 326 |
$player_actor
Группа: Проверенные
Сообщений: 559
Статус: Offline
| Vital, во время выполнения скрипта выводить что-либо на экран невозможно. Основной рендеринг происходит уже после того, как игра обработает скрипты.
|
|
| |
Vital | Дата: Понедельник, 24.06.2013, 21:25 | Сообщение # 327 |
Группа: Проверенные
Сообщений: 206
Статус: Offline
| Den_spb, хотел уточнить про for. Задержка в 0 мс нужна в каких случаях? Я имею в виду, при каком значении счётчика? Вот у меня такой цикл: Код for 0@ = 0 to 619 //4 0A90: 1@ = 32 * 0@ // int 1@ += 0x9788C0 И дальше проверки, 0A8D и в конце, при успешном выполнении всех условий, есть ещё 0A8C и wait 0 (только при успешном выполнении, просто для проверки производительности игры). Если идёт такое число, как 620, то игра не потеряет в производительности? Какое число максимальное в таком случае, и как его высчитать. Я, например, пробовал for для тысячи (или чуть более) объектов, причём выполнял не много действий над ними, но при этом игра притормаживала без wait 0.
SCRIPTER
|
|
| |
Den_spb | Дата: Понедельник, 24.06.2013, 21:40 | Сообщение # 328 |
Создатель сайта
Группа: Администраторы
Сообщений: 1603
Статус: Offline
| http://sannybuilder.com/forums/viewtopic.php?pid=16957#p16957
|
|
| |
Vital | Дата: Понедельник, 24.06.2013, 22:59 | Сообщение # 329 |
Группа: Проверенные
Сообщений: 206
Статус: Offline
| То есть, если я использую такой цикл, то надо подсчитать все повторения и умножить их на кол-во опкодов, правильно ли я понял? В таком случае, если считать все end и if, то выходит около 20 тысяч за цикл, при этом wait 0 может не выполниться вовсе, а может и выполниться, но только при удачном выполнении всего, что было ранее. В принципе, игра не тормозит и не выдаёт слайд шоу, что радует, но хотелось бы дополнительно узнать, влияет ли то, что я использую так много if для отбора нужного значения? P.S. Я опять вожусь с памятью, что-то удаётся сделать с пикапами, вот я их и хочу разобрать в цикле. Спасибо за ответы. Я порой думаю, что выгляжу для вас как полный нуб, который только достаёт вопросами...Добавлено (24.06.2013, 22:59) --------------------------------------------- Как рассчитать координаты пикапа через память? Я уже запарился над этими вычислениями, не понимаю системы, делю на 8, так как там умножено на 8, беру 2 байта (хотя float - это 4), пробовал после этого всё подряд, но ничего не работает... Странно, почему так. И каждый раз выходят нулевые координаты.
SCRIPTER
|
|
| |
DK22Pac | Дата: Вторник, 25.06.2013, 00:20 | Сообщение # 330 |
$player_actor
Группа: Проверенные
Сообщений: 559
Статус: Offline
| В ексе есть готовая функция, которая возвращает координаты пикапа (на входе - то ли сам пикап, то ли индекс). Жаль, у меня базы под рукой нет.
|
|
| |