You are not logged in.
Народ, кто знает, какие адреса отвечают за параметры машин?
Тема переименована для соответствия содержимому.
Last edited by Seemann (23-05-2010 18:27)
Offline
Если нужно прочитать/изменить какой-то параметр одного конкретного транспортного средства, то смотрим сюда: http://sannybuilder.com/forums/viewtopi … 6899#p6899 (смещения, которые нужно прибавлять к структуре, перечислены здесь: http://gtamodding.ru/wiki/Адреса_Памяти_(SA)#Cars)
Если нужно прочитать/изменить какие-то данные из загруженного в память игры handling-файла, то смотрим сюда: http://sannybuilder.com/forums/viewtopi … 9154#p9154 (необходимые адреса тут: http://gtamodding.ru/wiki/Адреса_Памяти_(SA)#Handling)
Offline
Спасибо!
Offline
И от меня спасибо
А где оффсет WreckedFlags для CTrain?
Last edited by ~AquaZ~ (09-05-2010 06:58)
Offline
@~AquaZ~ -
Младший бит по смещению byte[CVehicle + 0x5B9]
Offline
А что такое младший бит ?
Offline
Байт состоит из 8 битов, пронумерованных в обратном порядке (7 6 ... 2 1 0). Бит с номером 0 это и есть младший бит. Прочитать или записать значение бита (0 или 1) можно с помощью спец. опкодов (см. СБ справку - Статьи - Опытным пользователям - Работа с битами переменной).
Конкретно для заданного вопроса написал небольшой код, создающий поезд на станции СФ. Пока поезд на рельсах, в правом нижнем углу экрана будет высвечиваться 0, как только поезд сойдёт с рельсов появится 1.
{$CLEO} model.Load(#STREAK) repeat wait 0 until model.Available(#STREAK) 06D8: 0@ = create_train_at -1941.2332 191.4206 25.7028 type 15 direction 1 model.Destroy(#STREAK) 0A97: 1@ = car 0@ struct 1@ += 1465 while true wait 0 if 056E: car 0@ defined then 0A8D: 2@ = read_memory 1@ size 1 virtual_protect 0 03F0: enable_text_draw 1 if 08B4: test 2@ bit 0 then 045A: draw_text_1number 600.0 400.0 GXT 'NUMBER' number 1 // ~1~ else 045A: draw_text_1number 600.0 400.0 GXT 'NUMBER' number 0 // ~1~ end end end
Last edited by Den_spb (09-05-2010 22:46)
Offline
Всё так просто - младий бит == первый бит? Спасибо
[---]Поезд просто замирает, но с рельс не сходит
0A97: 1@ = car 0@ struct 1@ += 0x5B9 0A8D: 2@ = read_memory 1@ size 1 virtual_protect 0 08BA: set 2@ bit 0 0A8C: write_memory 1@ size 1 value 2@ virtual_protect 0
Last edited by ~AquaZ~ (10-05-2010 16:04)
Offline
После установки флага поезд считается сведенным с рельс. "Сбивать" его с пути нужно самим (установить velocity / acceleration каждому вагону в нужном направлении).
Last edited by Alien (10-05-2010 17:57)
Offline
Понял, спасибо![---]Эээ... Странный ГЛЮК... кинул velocity, тягач не сдвигается с места, но касание к нему выкидывает далеко - появляестя прямоугольник и надпись 'Loading...'
0208: 1@ = random_float_in_ranges -1.0 1.0 0407: store_coords_to 2@ 3@ 4@ from_car 0@ with_offset 1.0 1@ 0.1 07D5: set_car 0@ velocity_in_direction_XYZ 2@ 3@ 4@ rotation_velocitiesXY 0 0 unk 0
[---]Дал ускорение как поезду - стоит на месте, но сбивает!
Last edited by ~AquaZ~ (10-05-2010 18:19)
Offline
Я провёл аналогичный эксперимент, при этом игрок находился в поезде. После установки флага спидометр показывает бешеную скорость, однако поезд стоит на месте. Команды типа 07D5, 07DB не перемещают поезд, но после их применения спидометр показывает большее значение.
Пробовал телепортировать вагон (car.putAt) - работает, но поезд всёравно остаётся "замороженным" в последней точке своего пребывания. Прохожие, соприкасающиеся с вагоном, гибнут (поезд сбивает их, хотя на самом деле стоит на месте).
Ещё одно наблюдение - если включить флаг схода поезда, телепортировать поезд в какую-то точку, а потом выключить флаг, то поезд продолжит ехать по рельсам - с того места, откуда был телепортирован.
Offline
Хм, может его кидать через PutAt? Но это как-то совсем тупо - вручную расчитывать векторы...
Offline
{ 0A97: 1@ = car 0@ struct while 1@ <> 0 wait 0 0AA6: call_method 0x006F6320 struct 1@ num_params 0 pop 0 // 1@ += 0x5D4 0A8D: 1@ = read_memory 1@ size 4 virtual_protect 0 end } 0A97: 1@ = car 0@ struct while 1@ <> 0 0A8E: 2@ = 1@ + 0x40 // int 0A8E: 3@ = 1@ + 0x5B9 // int 0A8D: 4@ = read_memory 2@ size 4 virtual_protect 0 // *(dword*)(CVehicle + 0x40) 0A8D: 5@ = read_memory 3@ size 1 virtual_protect 0 // *(byte*)(CVehicle + 0x5B9) 0B10: 4@ = 4@ AND 0xFFFDFFFB // 0B11: 5@ = 5@ OR 0x01 // 0A8C: write_memory 2@ size 4 value 4@ virtual_protect 0 // *(dword*)(CVehicle + 0x40) &= 0xFFFDFFFB 0A8C: write_memory 3@ size 1 value 5@ virtual_protect 0 // *(byte*)(CVehicle + 0x5B9) |= 0x01 0A8D: 2@ = read_memory 1@ size 4 virtual_protect 0 // *(int*)CVehicle 2@ += 0x10 0A8D: 2@ = read_memory 2@ size 4 virtual_protect 0 0AA6: call_method 2@ struct 1@ num_params 1 pop 0 0 // 1@ += 0x5D4 0A8D: 1@ = read_memory 1@ size 4 virtual_protect 0 end { 0A97: 1@ = car 0@ struct 0AA6: call_method 0x005485E0 struct 1@ num_params 0 pop 0 }
[---]
CPU Disasm Address Hex dump Command Comments 006F8DC0 8BFE MOV EDI,ESI 006F8DC2 32C0 XOR AL,AL 006F8DC4 84C0 TEST AL,AL 006F8DC6 0F85 BD010000 JNE 006F8F89 006F8DCC 8BCF MOV ECX,EDI 006F8DCE E8 4DD5FFFF CALL 006F6320 006F8DD3 8BBF D4050000 MOV EDI,DWORD PTR DS:[EDI+5D4] 006F8DD9 85FF TEST EDI,EDI 006F8DDB ^ 75 E7 JNE SHORT 006F8DC4 006F8DDD 84C0 TEST AL,AL 006F8DDF 0F85 A4010000 JNE 006F8F89 006F8DE5 8BFE MOV EDI,ESI 006F8DE7 BB FBFFFDFF MOV EBX,FFFDFFFB 006F8DEC 8D6424 00 LEA ESP,[ESP] 006F8DF0 8B57 40 MOV EDX,DWORD PTR DS:[EDI+40] 006F8DF3 8A87 B9050000 MOV AL,BYTE PTR DS:[EDI+5B9] 006F8DF9 23D3 AND EDX,EBX 006F8DFB 0C 01 OR AL,01 006F8DFD 8957 40 MOV DWORD PTR DS:[EDI+40],EDX 006F8E00 8B17 MOV EDX,DWORD PTR DS:[EDI] 006F8E02 6A 00 PUSH 0 006F8E04 8BCF MOV ECX,EDI 006F8E06 8887 B9050000 MOV BYTE PTR DS:[EDI+5B9],AL 006F8E0C FF52 10 CALL DWORD PTR DS:[EDX+10] 006F8E0F 8BBF D4050000 MOV EDI,DWORD PTR DS:[EDI+5D4] 006F8E15 85FF TEST EDI,EDI 006F8E17 ^ 75 D7 JNE SHORT 006F8DF0 006F8E19 8BCE MOV ECX,ESI 006F8E1B E8 C0F7E4FF CALL 005485E0
Last edited by Sanchez (05-06-2010 17:57)
Offline
2Den_spb:
0B10 и 0B11 - это битовые операции.
Операция И.
Допустим есть два числа, напишу без ведущих нолей.
23 = 01 0111
38 = 10 0110
Рассматриваем побитово, если биты обоих чисел под одним номером единичные, бит под тем же номером результирующего числа будет единицей.
6 = 00 0110
Операция ИЛИ.
Если хоть один бит из тех двух единичный, записываем единицу.
23 = 01 0111
38 = 10 0110
55 = 11 0111
В языках высокого уровня эти операции записываются как & и |.
a = b & c; //AND d = e | f; //OR
[---]
2Sanchez:
Твой код тормозит поезд и вылетает
Last edited by ~AquaZ~ (11-05-2010 06:00)
Offline
@Den_spb -
Логическая операция:
0B10: 4@ = 4@ AND 0xFFFDFFFB
AND применяют для выборочного обнуления отдельных бит:
0B10: 4@ = 4@ AND 11111111111111011111111111111011b
т.е. обнуляется 2-ой и 17-ый бит, остальные не изменяются. Равносильно командам:
08C3: clear 4@ bit 2 08C3: clear 4@ bit 17
Логическая операция:
0B11: 5@ = 5@ OR 0x01
OR чаще всего используют для выборочной установки отдельных бит:
0B11: 5@ = 5@ OR 00000001b
т.е. устанавливается 0-ой бит. Равносильно командe:
08BD: set 5@ bit 0
[---]
@~AquaZ~ -
Впринципе и этого достаточно, чтобы свести поезд с рельс:
0A97: 1@ = car 0@ struct while 1@ <> 0 0A8E: 2@ = 1@ + 0x40 // int 0A8E: 3@ = 1@ + 0x5B9 // int 0A8D: 4@ = read_memory 2@ size 4 virtual_protect 0 // *(dword*)(CVehicle + 0x40) 0A8D: 5@ = read_memory 3@ size 1 virtual_protect 0 // *(byte*)(CVehicle + 0x5B9) 0B10: 4@ = 4@ AND 0xFFFDFFFB // 0B11: 5@ = 5@ OR 0x01 // 0A8C: write_memory 2@ size 4 value 4@ virtual_protect 0 // *(dword*)(CVehicle + 0x40) &= 0xFFFDFFFB 0A8C: write_memory 3@ size 1 value 5@ virtual_protect 0 // *(byte*)(CVehicle + 0x5B9) |= 0x01 1@ += 0x5D4 0A8D: 1@ = read_memory 1@ size 4 virtual_protect 0 end
Last edited by Sanchez (11-05-2010 06:37)
Offline
Sanchez, почему я не могу код скомпилировать? Недостаточно параметров. Ожидалось 7 параметров.
Это вроде из-за 0b11: 5@ = 5@ or 0x01
Offline
@Sanchez - Ага! Теперь понятно, в чем была основная ошибка:
флаг нужно было выставлять для всех варонов поезда (0x5D4 - указатель на седующий вагон)
Иначе получалось, что в голове/середине поезда образовался один сошедший с рельсов вагон.
Offline
У меня всё скомпилилось, но игра на этом месте вылетает.
А смещение 0x5D4 от структуры хранит смещение след. вагона, или хэндл?
Last edited by ~AquaZ~ (11-05-2010 12:34)
Offline
@~AquaZ~ - US1.0 (stripped.scm)
{$CLEO} // for test Actor.PutAt($PLAYER_ACTOR, 2304.6182, -1334.5227, 23.842) Actor.Angle($PLAYER_ACTOR) = 17.5234 0AD1: show_formatted_text_highpriority "~r~Press F4" time 5000 // #FREIFLAT.Load #FREIGHT.Load 038B: load_requested_models 06D8: 0@ = create_train_at 2285.152 -1257.5 23.0 type 13 direction 1 06DC: set_train 0@ acc 20.0 while true wait 0 if 0AB0: key_pressed 0x73 then 0A97: 1@ = car 0@ struct while 1@ <> 0 0A8E: 2@ = 1@ + 0x40 // int 0A8E: 3@ = 1@ + 0x5B9 // int 0A8D: 4@ = read_memory 2@ size 4 virtual_protect 0 0A8D: 5@ = read_memory 3@ size 1 virtual_protect 0 0B10: 4@ = 4@ AND 0xFFFDFFFB 0B11: 5@ = 5@ OR 0x01 0A8C: write_memory 2@ size 4 value 4@ virtual_protect 0 // *(dword*)(CVehicle + 0x40) &= 0xFFFDFFFB 0A8C: write_memory 3@ size 1 value 5@ virtual_protect 0 // *(byte*)(CVehicle + 0x5B9) |= 0x01 1@ += 0x5D4 // next carriage 0A8D: 1@ = read_memory 1@ size 4 virtual_protect 0 end Break end end 0A93: end_custom_thread
[---]
dd[+0x5D0] - prev carriage dd[+0x5D4] - next carriage
Last edited by Sanchez (11-05-2010 12:57)
Offline
1.0 US Stripped (облегчённая)
мгновенно вылетает...
Offline
@~AquaZ~ - Указатель. Хэндлы используются только внутри скриптов
Вообще, смысл хэндла - удостовериться в том, что за время пока скрипт спал, сборщик мусора не удалил нужную машину (педа, объект). Внутри нативного кода такой проблемы нет (для этого используется механизм reference).
Кстати, надо учитывать, что +0x5D4 (m_pNextCarriage) есть только в CTrain, поэтому, в общем случае, стоит проверять, что обрабатываемый vehicle является поездом.
Offline
Так, а как получить оффсет, имея хендл?
Offline