#1 08-05-2010 21:41

Skripter
Registered: 06-05-2010
Posts: 2

[SA] Как свести поезд с рельс?

Народ, кто знает, какие адреса отвечают за параметры машин?

Тема переименована для соответствия содержимому.

Last edited by Seemann (23-05-2010 18:27)

Offline

#2 08-05-2010 22:33

Den_spb
From: Ленинград
Registered: 23-11-2008
Posts: 941
Website

Re: [SA] Как свести поезд с рельс?

Если нужно прочитать/изменить какой-то параметр одного конкретного транспортного средства, то смотрим сюда: 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

#3 08-05-2010 22:44

Skripter
Registered: 06-05-2010
Posts: 2

Re: [SA] Как свести поезд с рельс?

Спасибо! smile

Offline

#4 09-05-2010 06:44

~AquaZ~
Registered: 01-03-2010
Posts: 726

Re: [SA] Как свести поезд с рельс?

И от меня спасибо smile
А где оффсет WreckedFlags для CTrain?

Last edited by ~AquaZ~ (09-05-2010 06:58)

Offline

#5 09-05-2010 09:01

Sanchez
Registered: 18-08-2006
Posts: 280

Re: [SA] Как свести поезд с рельс?

@~AquaZ~ -
Младший бит по смещению byte[CVehicle + 0x5B9]

Offline

#6 09-05-2010 13:24

~AquaZ~
Registered: 01-03-2010
Posts: 726

Re: [SA] Как свести поезд с рельс?

А что такое младший бит smile ?

Offline

#7 09-05-2010 22:44

Den_spb
From: Ленинград
Registered: 23-11-2008
Posts: 941
Website

Re: [SA] Как свести поезд с рельс?

Байт состоит из 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

#8 10-05-2010 15:59

~AquaZ~
Registered: 01-03-2010
Posts: 726

Re: [SA] Как свести поезд с рельс?

Всё так просто - младий бит == первый бит? Спасибо smile
[---]Поезд просто замирает, но с рельс не сходит

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

#9 10-05-2010 17:27

Den_spb
From: Ленинград
Registered: 23-11-2008
Posts: 941
Website

Re: [SA] Как свести поезд с рельс?

Видимо, с помощью этого флага можно только узнать состояние поезда.

Last edited by Den_spb (10-05-2010 17:41)

Offline

#10 10-05-2010 17:56

Alien
Registered: 12-10-2008
Posts: 564

Re: [SA] Как свести поезд с рельс?

После установки флага поезд считается сведенным с рельс. "Сбивать" его с пути нужно самим (установить velocity / acceleration каждому вагону в нужном направлении).

Last edited by Alien (10-05-2010 17:57)

Offline

#11 10-05-2010 17:59

~AquaZ~
Registered: 01-03-2010
Posts: 726

Re: [SA] Как свести поезд с рельс?

Понял, спасибо![---]Эээ... Странный ГЛЮК... кинул velocity, тягач не сдвигается с места, но касание к нему выкидывает далеко - появляестя прямоугольник и надпись 'Loading...' wink

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

#12 10-05-2010 20:29

Den_spb
From: Ленинград
Registered: 23-11-2008
Posts: 941
Website

Re: [SA] Как свести поезд с рельс?

Я провёл аналогичный эксперимент, при этом игрок находился в поезде. После установки флага спидометр показывает бешеную скорость, однако поезд стоит на месте. Команды типа 07D5, 07DB не перемещают поезд, но после их применения спидометр показывает большее значение.
Пробовал телепортировать вагон (car.putAt) - работает, но поезд всёравно остаётся "замороженным" в последней точке своего пребывания. Прохожие, соприкасающиеся с вагоном, гибнут (поезд сбивает их, хотя на самом деле стоит на месте).
Ещё одно наблюдение - если включить флаг схода поезда, телепортировать поезд в какую-то точку, а потом выключить флаг, то поезд продолжит ехать по рельсам - с того места, откуда был телепортирован.

Offline

#13 10-05-2010 21:17

~AquaZ~
Registered: 01-03-2010
Posts: 726

Re: [SA] Как свести поезд с рельс?

Хм, может его кидать через PutAt? Но это как-то совсем тупо - вручную расчитывать векторы...

Offline

#14 10-05-2010 21:25

Den_spb
From: Ленинград
Registered: 23-11-2008
Posts: 941
Website

Re: [SA] Как свести поезд с рельс?

Можно не "в ручную", а циклом, но всё равно это не очень хороший вариант. Наверное во время схода поезда с рельсов помимо изменения значения флага происходит ещё что-то.

Offline

#15 10-05-2010 23:15

Sanchez
Registered: 18-08-2006
Posts: 280

Re: [SA] Как свести поезд с рельс?

{
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

#16 11-05-2010 02:09

Den_spb
From: Ленинград
Registered: 23-11-2008
Posts: 941
Website

Re: [SA] Как свести поезд с рельс?

Я так понимаю, код производит какие-то действия над всеми вагонами одного поезда? А что за опкоды 0B10 и 0B11 ?

Offline

#17 11-05-2010 05:56

~AquaZ~
Registered: 01-03-2010
Posts: 726

Re: [SA] Как свести поезд с рельс?

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:
Твой код тормозит поезд и вылетает wink

Last edited by ~AquaZ~ (11-05-2010 06:00)

Offline

#18 11-05-2010 06:13

Sanchez
Registered: 18-08-2006
Posts: 280

Re: [SA] Как свести поезд с рельс?

@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

#19 11-05-2010 07:24

GTASA
Registered: 13-09-2008
Posts: 476

Re: [SA] Как свести поезд с рельс?

Sanchez, почему я не могу код скомпилировать? Недостаточно параметров. Ожидалось 7 параметров.
Это вроде из-за 0b11: 5@ = 5@ or 0x01

Offline

#20 11-05-2010 08:22

listener
From: Vice City
Registered: 09-11-2006
Posts: 616
Website

Re: [SA] Как свести поезд с рельс?

@Sanchez - Ага! Теперь понятно, в чем была основная ошибка:

флаг нужно было выставлять для всех варонов поезда (0x5D4 - указатель на седующий вагон)
Иначе получалось, что в голове/середине поезда образовался один сошедший с рельсов вагон.

Offline

#21 11-05-2010 12:27

~AquaZ~
Registered: 01-03-2010
Posts: 726

Re: [SA] Как свести поезд с рельс?

У меня всё скомпилилось, но игра на этом месте вылетает.
А смещение 0x5D4 от структуры хранит смещение след. вагона, или хэндл?

Last edited by ~AquaZ~ (11-05-2010 12:34)

Offline

#22 11-05-2010 12:42

Sanchez
Registered: 18-08-2006
Posts: 280

Re: [SA] Как свести поезд с рельс?

@~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

#23 11-05-2010 12:45

~AquaZ~
Registered: 01-03-2010
Posts: 726

Re: [SA] Как свести поезд с рельс?

1.0 US Stripped (облегчённая)
мгновенно вылетает...

Offline

#24 11-05-2010 12:54

listener
From: Vice City
Registered: 09-11-2006
Posts: 616
Website

Re: [SA] Как свести поезд с рельс?

@~AquaZ~ - Указатель. Хэндлы используются только внутри скриптов
Вообще, смысл хэндла - удостовериться в том, что за время пока скрипт спал, сборщик мусора не удалил нужную машину (педа, объект). Внутри нативного кода такой проблемы нет (для этого используется механизм reference).

Кстати, надо учитывать, что +0x5D4 (m_pNextCarriage) есть только в CTrain, поэтому, в общем случае, стоит проверять, что обрабатываемый vehicle является поездом.

Offline

#25 11-05-2010 13:04

~AquaZ~
Registered: 01-03-2010
Posts: 726

Re: [SA] Как свести поезд с рельс?

Так, а как получить оффсет, имея хендл?

Offline

Board footer

Powered by FluxBB