Итак, первый посыл: адреса памяти San Andreas могут меняться также легко через SCM.
Более подробно об этом написано в статье Меняем игровую память через SCM (San Andreas).
Второй посыл: опкод:
- Code:
06D8: $hTrain = create_train_at 2285.1524 -1257.4997 23.0 type 0 direction 1
Он создает поезд с определенным числом вагонов. Вид поезда, количество вагонов определяется параметром type.
Всего существует 16 типов поездов:
- Code:
Train Carriage1 Carriage2 Carriage3 Carriage4 Carriage5
----------------------------------------------------------------------------
0: #FREIGHT #FREIFLAT #FREIFLAT #FREIFLAT #FREIFLAT x
1,2,4,7,11: #STREAK #STREAKC #STREAKC x x x
3: #FREIGHT #FREIFLAT #FREIFLAT #FREIFLAT x x
5: #STREAK #STREAKC #STREAKC #STREAKC x x
6: #FREIGHT #FREIFLAT #FREIFLAT x x x
8: #TRAM #TRAM x x x x
9,14: #TRAM x x x x x
10: #FREIGHT #FREIFLAT x x x x
12: #FREIGHT #FREIFLAT #FREIFLAT #FREIFLAT #FREIGHT x
13: #FREIGHT #FREIFLAT #FREIFLAT #FREIFLAT #FREIFLAT #FREIFLAT
15: #STREAK x x x x x
Третий посыл: в San Andreas есть адрес 0x8D44F8.
Данный адрес - это начало перечня моделей для каждого типа поезда. Всего определено 16 блоков-перечней (по числу типов), каждый из которых содержит 16 чисел типа DWord, определяющих номер модели поезда и его вагонов.
Например, тип 0 содержит записанные подряд числа: 537, 569, 569, 569, 569, 0, 0, 0, 0, 0 и т.д.
Адреса всех типов:
- Code:
0x8D44F8 тип 0
0x8D4538 тип 1
0x8D4578 тип 2
0x8D45B8 тип 3
0x8D45F8 тип 4
0x8D4638 тип 5
0x8D4678 тип 6
0x8D46B8 тип 7
0x8D46F8 тип 8
0x8D4738 тип 9
0x8D4778 тип 10
0x8D47B8 тип 11
0x8D47F8 тип 12
0x8D4838 тип 13
0x8D4878 тип 14
0x8D48B8 тип 15
Четвертый посыл: подпрограмма создания поезда читает эти цифры до тех пор, пока не найдет 0.
Анализируя эти посылы, легко догадаться что можно изменить типы поездов, чтобы создавать свои собственные вариации с очень большим числом вагонов (мне удавалось создавать 18 вагонов, хотя я не тестировал это детально).
Данные адреса памяти относятся к типу Data, так что их можно менять прямо в игре.
Собственно, сам код:
- Code:
for 0@ = -382229 to -382216
wait 0
&0(0@,1i) = #STREAKC
end
Этим циклом мы добавили 14 новых вагонов #STREAKC к типу 0 (т.е. к 4-м уже существующим вагонам, хотя ничто не мешало нам перезаписать старые модели и создать абсолютно новый тип).
О принципе получения чисел в цикле можно прочитать здесь.
Теперь можно создавать поезд.
- Code:
// type "test"
:Trains_01
wait 0
2@ = -229908
if
&0(2@,1i) == 0x54455354
jf @Trains_01
&0(2@,1i) = 0x54455300
03E5: show_text_box 'CHEAT1' // Cheat activated
0169: set_fade_color_RGB 0 0 0
fade 0 time 500
while true
if
not fading
then
break
end
wait 0
end
// type 0 has been changed! ADDED 14 more now carriages to the train
for 0@ = -382229 to -382216
wait 0
&0(0@,1i) = #STREAKC
end
#FREIGHT.Load
#FREIFLAT.Load
#STREAKC.Load
while true
if and
Model.Available(#FREIGHT)
Model.Available(#FREIFLAT)
Model.Available(#STREAKC)
then
break
end
wait 0
end
Actor.PutAt($PLAYER_ACTOR, 2270.1771, -1144.8823, 27.5108)
03CB: set_rendering_origin_at 2270.1771 -1144.8823 27.5108
04E4: unknown_refresh_game_renderer_at 2270.1771 -1144.8823
wait 1300
fade 1 time 1500
while true
if
fading
then
break
end
wait 0
end
// create train with new carriages
06D8: 1@ = create_train_at 2278.1771 -1144.8823 27.5108 type 0 direction 1
0395: clear_area 1 at 2270.1771 -1144.8823 27.5108 radius 1.0
Model.Destroy(#FREIGHT)
Model.Destroy(#FREIFLAT)
Model.Destroy(#STREAKC)
end_thread
Поезд с 18 вагонами создан. Наслаждайтесь .
З.Ы. При изменении типов имейте в виду, что при укорачивании поезда (уменьшении числа вагонов в данном типе), необходимо ненужные вагоны перезаписывать в ноль.
Берем адрес первого набора вагонов: 0x8D44F8
Смотрим в подпрограмму:
- Code:
:MemoryWrite_DWORD
0@ -= 0xA49960
0@ /= 4
008A: &0(0@,1i) = 1@
return
Теперь подставляем вместо 0@ наш адрес и считаем:
- Code:
0x8D44F8 - 0xA49960 = 0xFFE8AB98 (-1528936)
-1528936 / 4 = -382234
-382234 это будет адрес для первого элемента в записи. В первом типе в этой ячейке записано #FREIGHT (смотри таблицу). Нам первые 4 вагона и сам локомотив не нужно менять (хотя, как я и говорил, ничто не мешает это сделать), поэтому мы прибавляем 5 к данному числу и получаем адрес для 5го вагона: -382229. В оригинальной игре этот адрес содержит 0, поэтому тип 0 создает только 4 вагона. И вот мы начинаем записывать новые значения циклом.
- Code:
-382229 - 5й вагон
-382228 - 6й вагон
и т.д.
Игра, когда парсит массив &0(0@,1i), она это -382229 преобразует в нужный глобальный адрес.
Также см.:
[SA|MEMORY] Поезда. Лимит вагонов.
SA Memory Topic
SA Memory handling, some tricks using SA arrays