Скрипт для GTA San Andreas позволяет использовать массивы. Эту возможность я добавил и в генератор. Я рекомендую научится ими пользоваться, так как это существенно ускоряет разработку миссий и позволяет сократить количество ручного кода.
Генератор поддерживает практически все типы данных. Чтобы создать массив, нам нужно определиться будет ли он глобальным и какой тип он будет представлять. Базовый синтаксис такой:
[Thread]
public void TEST() {
var pedArray = Array<Actor>.local( 0, 10 ); // 0@ - 9@
end_thread();
}
Генератор теперь будет знать, что "pedArray" - это массив, который начинается с индекса 0 и имеет 10 элементов. Тип данных будет "Actor". Это значит, что количество переменных, которые ему будут доступны - 10.
После этого мы можем обращаться к массиву по индексу и давать команды, которые есть у указанного типа данных:
[Thread]
public void TEST() {
var pedArray = Array<Actor>.local( 0, 10 ); // 0@ - 9@
pedArray[ 0 ].create_random( 0.0, 1.0, 2.0 );
pedArray[ 1 ].create_random( 1.0, 1.0, 2.0 );
pedArray[ 2 ].create_random( 2.0, 1.0, 2.0 );
// ...
pedArray[ 9 ].create_random( 9.0, 1.0, 2.0 );
end_thread();
}
Если тип требует более одной переменной, то генератор это будет учитывать и делать нужные отступы. Это требуют только два типа данных: "sString" и "vString":
[Thread]
public void TEST() {
var pedArray = Array<Actor>.local( 0, 2 ); // 0@ - 1@
pedArray[ 0 ].create_random( 0.0, 1.0, 2.0 );
pedArray[ 1 ].create_random( 1.0, 1.0, 2.0 );
var stringArray = Array<vString>.local( 2, 3 ); // 2@,3@,4@,5@ 6@,7@,8@,9@ 10@,11@,12@,13@
stringArray[ 0 ].value = "str 0";
stringArray[ 1 ].value = "str 1";
stringArray[ 2 ].value = "str 2";
end_thread();
}
Мы увидим смещение в результате:
:TEST 03A4: name_thread 'TEST' 0376: 0@ = create_random_actor_at 0.0 1.0 2.0 0376: 1@ = create_random_actor_at 1.0 1.0 2.0 06D2: 2@v = "str 0" // @v = ? (vstring) 06D2: 6@v = "str 1" // @v = ? (vstring) 06D2: 10@v = "str 2" // @v = ? (vstring) 004E: end_thread
Заметно, что никаких массивов не используется на выходе. Здесь активно внедрён трюк с переменными, который позволяет объединять переменные в массивы. Мы можем вызвать метод "each", который будет делать указанное действие с каждым элементом массива:
[Thread]
public void TEST() {
var index = Int.local( 0 ); // 0@
var strArray = Array<sString>.local( 1, 5 ); // 1@,2@ 3@,4@ 5@,6@ 7@,8@ 9@,10@
strArray.each( index, elem => {
elem.value = sString.DUMMY;
} );
end_thread();
}
Внутри этой команды "вшит" цикл, который требует перменную-счётчик. Парматер "elem" нужно для того, чтобы работать с элементом массива. Мы можем использовать и ручной цикл, передав переменную счётчик в индекс массива:
[Thread]
public void TEST() {
var index = Int.local( 0 ); // 0@
var strArray = Array<sString>.local( 1, 5 ); // 1@,2@ 3@,4@ 5@,6@ 7@,8@ 9@,10@
strArray.each( index, elem => {
elem.value = sString.DUMMY;
} );
// ручной перебор массива
to( index, 0, strArray.count, delegate {
strArray[ index ].value = "DUMMY";
} );
end_thread();
}
Оба варианта будут генерировать одно и тоже. Только первый делает это быстрее. Вот результат:
//------------- TEST --------------- :TEST 03A4: name_thread 'TEST' for 0@ = 0 to 5 05AA: 1@(0@,5s) = 'DUMMY' // @s = ? (sstring) end int 0@ for 0@ = 0 to 5 05AA: 1@(0@,5s) = 'DUMMY' // @s = ? (sstring) end 004E: end_thread
Мы можем изменть размер массива. Но это надо делать осторожно и лучше использовать это не более 1 раза за скрипт:
[Thread]
public void TEST() {
var index = Int.local( 0 ); // 0@
var strArray = Array<sString>.local( 1, 5 ); // 1@,2@ 3@,4@ 5@,6@ 7@,8@ 9@,10@
strArray.each( index, elem => {
elem.value = sString.DUMMY;
} );
strArray.Resize( 4 ); // 1@,2@ 3@,4@ 5@,6@ 7@,8@
strArray.each( index, elem => {
elem.value = sString.DUMMY;
} );
end_thread();
}
На самом деле изменения как такового нету. Просто в циклах изменится размер:
//------------- TEST --------------- :TEST 03A4: name_thread 'TEST' for 0@ = 0 to 5 // изначальный размер 05AA: 1@(0@,5s) = 'DUMMY' // @s = ? (sstring) end for 0@ = 0 to 4 // после изменения размера 05AA: 1@(0@,4s) = 'DUMMY' // @s = ? (sstring) end 004E: end_thread
Изменения размера хорошо использовать в миссиях, где часто нужно создавать разное количество врагов и маркеров над ними. Тогда достаточно перед началом миссии изменить размер.