Переменные, типы данных
Sanny Builder даёт возможность использовать тип данных как переменную класса, но их количество ограниченно и приходилось вручную писать классы и их методы. Генератор же использует все типы данных и сейчас мы научимся их создавать.
Начну с простых вещей. Типы условно можно разделить на числовые и строковые. Они описывают данные переменных, которые могут быть локальными или глобальными. Если в Sanny Builder нам достаточно было использовать символы @ и $ чтобы указать локальная переменная или нет, то в генераторе этот механизм совсем иной. Сначала нужно объявить переменную.
Инициализация
Начиная с версии 7.0, нам уже не нужно предварительно инициализировать переменные. Это происходит автоматически в таком порядке: слева на право и сверху вниз. Это происходит только в том случае, если они небыли инициализированы ранее. Пример такой инициализации:
Всё, что помечено ключевым словом static
при такой инициализации будет воспринято генератором как глобальная переменная. Это будет эквивалентно следующему коду:
Если использовать команды local
и global
, то переменная получит контекст независимо от использования ключевого слова static. Такое использование позволяет инициализировать переменную где угодно. Например, внутри метода:
До этого мы рассматривали примеры, когда переменные получали номера автоматически. Но я оставил возможность явно указывать какой номер будет использоваться при инициализации. Подход применяется в случае, когда лимит исчерпан и нужно перезаписать существующую переменную. Пример:
Переменные myLocalVariable1 и myLocalVariable2 будут ссылаться на один и тот же номер. При этом мы можем указывать разные типы. Недостатком такого подхода будет контроль за номерами — нам нужно точно знать какой номер получила автоматическая переменная, чтобы потом явно его указать.
Типы sString и vString в библиотеках GTA.III и GTA.VC номер не получают, так как в скриптах не предусмотрено использование строк в качестве переменных! Они декоративные.
Типы sString и vString в библиотеке GTA.SA делают сдвиг номера, так как они занимают больше места, чем остальные типы данных! Это затруднит поиск номера при явном указании переменной.
Установка числовых значений
Установка значения происходит путём вызова свойства value
, что не совсем удобно. Это связано как с ограничениями языка программирования, так и с передачей параметров в методы. Поскольку в C# строгая типизация, то задавать значения можно только переменные одного типа. Для чисел и строк существует больше вариантов установки значений. Давайте рассмотрим пример:
Как видим, нет ничего страшного в использовании value. Отдельно хотелось обратить внимание, что строки не имеют привязки к конкретному виду кавычек. Все они пишутся в двойных. Генератор будет использовать те, что закреплены в Sanny Builder. Если длина строки не будет соответствовать своему типу, то генератор сообщит об ошибке.
C#, конечно, позволяет устанавливать значения переменным через символ =
. Но в контексте генератора использовать его НЕ СТОИТ! Суть в том, что C# устанавливает новую ссылку или значение (делает копию, грубо говоря). Генератор не может перехватить эту процедуру из за ограничений языка программирования.
Давайте рассмотрим пример того, как НЕ СТОИТ делать:
Каков результат? Вот:
В коде мы чётко указали, что counter является локальной переменной. Но в результате мы увидели, что используется переменная total. Выражение counter = total
заставило counter взять ссылку на total. Поэтому, если нужно записать значение total в переменную counter, используем свойство value
:
Осталось разобраться с переменной score. Что с ней "не так"? Переменные могут быть параметрами опкодов, поэтому генератор и C# позволяют делать подобную запись. Вся "соль" в том, что переменная score не будет иметь контекста (то есть не будет локальной или глобальной). Это значит, что все команды типа Int не будут правильно работать, так как нет опкода, который записывал бы значение в литерал. Следующий код будет генерировать ошибку:
Решением будет использовать методы local
или global
:
Результат:
В библиотеках GTA.III и GTA.VC строки могут без ограничений использовать прямую инициализацию, так как типы данных строк представлены только в виде литералов. Следующий код не будет вызывать проблем:
Арифметические операции
Некоторые типы данных поддерживают арифметические операции. Я рекомендую использовать их по очереди, хоть генератор позволяет нам делать сложные конструкции:
Использование сложных конструкций часто приводит к непредсказуемым результатам, поэтому лучше не использовать их вовсе. Вот результат:
Обратите внимание, что дробные числа записываются без каких либо суффиксов (F
или f
в C#). Это связано с тем, что фактически используется тип double
, а не float. Также генератор чувствителен к типам. Если Sanny Builder мог позволить записать в переменную типа Int дробное значение, то генератор этого не позволит сделать. Это нужно для контроля типов. Другими словами: чтобы не допускать логических ошибок, которые приводят к неожиданным результатам уже в игре.
Мы можем задавать дробному типу значения целого числа. Генератор сам преобразует его в дробный вид.
Встроенные переменные
Класс Thread (и другие подобные ему классы) имеет в своём составе некоторые переменные, которые можно использовать не инициализируя их. Таблица с именами находится в конце раздела. Давайте создадим игрока, дадим одежду и контроль (для GTA III и VC код будет немного другим):
Многие названия опкодов были переименованы согласно оригиналу, но обычно они не так часто используются. Для аргументов команд есть альтернативные значения — перечисления (для удобства). В примере выше я использовал перечисление ClothesBodyPart
, которое хранит номера частей тела игрока. Таких перечислений много. Обычно они имеют такое же название как и имя аргумента команды. Если мы скомпилируем этот код, то у нас будет такой скрипт:
Если скомпилировать в Sanny Builder, то в игре мы уже сможем управлять игроком и делать прочие базовые вещи:
Напоследок ещё расскажу о механизме вызовов методов. Нам не обязательно каждый раз писать имя переменной перед командой. Методы типов данных возвращают ссылку на переменную. Мы можем это использовать для реализации так называемой цепочки.Это будет выглядеть так:
Названия типов данных ВСЕГДА пишутся с прописной буквы! "Int" и "int" — это разные вещи.
Глобальные переменные между скриптами
Начиная с версии 5.0 нельзя получать доступ к полям единого класса. Это приводит к тому, что мы не можем использовать общие переменные. Решением будет использовать переменные с модификатором static
. Чтобы упростить доступ, можно все классы скриптов писать внутри класса MAIN. Для этого я как раз использовал модификатор partial
класса MAIN в этих примерах. Вот пример того, как организовать глобальный доступ:
Таким образом, мы можем обеспечить глобальный доступ между классами.
Базовые типы данных
Тип | SA | VC | III |
Числа | |||
Int, Float, Timer, StatusText, Memory | + | + | + |
Строки | |||
sString, vString | + | ||
Остальные | |||
Actor, Boat, Car, CashPickup, Checkpoint, File, Fire, Library, Marker, Object, Pickup, Player, RadarMarker, Sphere | + | + | + |
Garage, Phone, Sound | + | + | |
ObjectPath | + | ||
AssetMoneyPickup, Heli, Plane, Bike | + | + | |
Array, ASPack, Attractor, AudioStream, AudioStream3D, Cab, CarComponent, Carriage, ColorPanel, DecisionMaker, EntranceMarker, Group, GroupDecisionMaker, Panel, Particle, RaceCheckpoint, SearchFile, Searchlight, Trailer, Train | + |
Вспомогательные типы данных
Тип | SA | VC | III |
Декоративные типы | |||
sString, vString | + | + | |
Классы-одиночки | |||
CAR_PARK, DRAW, CAMERA, FXT | + | + | + |
Статические классы | |||
Model, Ini | + | + | + |
Garage | + |
Переменные по умолчанию
Имя | Тип | SA | VC | III |
OnMission, DefaultWaitTime, LocalTimer1, LocalTimer2 | Int | + | + | + |
PlayerChar | Player | + | + | + |
PlayerActor | Actor | + | + | + |
PlayerGroup | Group | + |
Last updated