Теперь перейдем к математическим действиям в скриптах. Числа в VCBM бывают двух типов: целые и дробные. Например, количество патронов в пикапе оружия является целым числом, а координаты или угол дробным. Для разных типов есть разные опкоды, то есть для сложения двух целых чисел один опкод, а для сложения дробных - другой и тд. Итак, раз упомянули сложение, то с него и начнем.
0008: $test += 1 - прибавление к переменной $test, которая является целочисленной переменной, числа 1.
0009: $test += 2.5 - прибавление к дробной переменной $test числа 2.5
Далее перейдем к вычитанию.
000C: $test -= 1 - вычитание целого числа
000D: $test -= 1.5 - тоже самое для дробного
Далее я буду писать только опкоды без примеров, думаю вы и сами догадаетесь что к чему.
0010 - умножение на целое число
0011 - умножение на дробное
Опкоды 0014 и 0015 служат для деления на целое и дробное число соответственно.
Замечу, что если вам надо прибавить, вычесть, умножить или разделить дробную переменную на целое число, то вам надо добавить к этому чилсу .0. То есть если мы имеем переменную $test, равную, например 2.4, то чтобы разделить эту переменную на 2, нужно использовать команду 0015: $test /= 2.0, что даст нам результат $test = 1.2
Так же в скриптах есть операции присвоения. Они также различны для разных типов. Для приравнения переменной $test целого числа, например 2, нужно использовать 0004: $test = 0, а для приравнения к дробному числу, например, 2.5 - 0005: $test = 2.5
Тут думаю все понятно. Теперь, думаю, стоит рассказать о данных, которые вы можете получить из игры. Например, здоровье машины или ее скорость, здоровье игрока или отдельно взятого персонажа и т.п.
03C1: $player_car = player $PLAYER_CHAR car - привязка машины игрока к переменной $player_car. Теперь через эту переменную можно будет обращаться к машине, ее параметрам и тд...
0227: $car_health = car $player_car health - в связке с предыдущей командой кинет в переменную $car_health здоровье машины игрока. Является целым числом. Замечу, что $player_car, может быть и id любой машины, созданной внутри скрипта, но об этом подробнее в главе 3.
02E3: $car_speed = car $player_car speed - присвоит переменной $car_speed скорость машины, в данном случае машины игрока. Является дробным числом, выражается в неизвестно каких единицах, чтобы получить км/ч нужно умножить на 4.0
0225: $player_health = player $PLAYER_CHAR health - присвоит переменной $player_health значение здоровья игрока. Является целым числом.
0226: $actor_health = actor $test_act health - теперь переменная $actor_health равна здоровью персонажа $test_act. О создании таких персонажей см. главу 2.
010B: $player_money = player $PLAYER_CHAR money - в переменную $player_money сохраняется количество денег у игрока.
Также некоторым из вышеперечисленны параметров можно присваивать свои значения.
04BA: set_car $player_car speed_instantly 20.0 - присвоить машине игрока скорость 80 км/ч. Почему тогда написано 20.0? Не забыли что я говорил про выражение скорости в команде 02E3: $car_speed = car $player_car speed ?
00AD: set_car $test_car max_speed_to 20.0 - установить машине $test_car максимальной скорости в 80 км/ч (напомню, максимум 50.0). Не работает на машине игрока, для нее берется значение из handling.cfg
0224: set_car $player_car health_to 1000 - установка машине игрока здоровья в 1000 единиц. Стандартным для любой машины здоровьем является 1000.
0222: set_player $PLAYER_CHAR health_to 200 - установка игроку 200 процентов здоровья
035E: set_player $PLAYER_CHAR armour_to 200 - то же самое только для бронежилета
055E: set_player $PLAYER_CHAR max_health += 50 - установка максимального значения здоровья, при чем имеет хитрую систему. Поначалу максимальное здоровье равно 100. Этой командой вы увеличите его на 50. Больше чем на 50 увеличивать нельзя, то есть команда 055E: set_player $PLAYER_CHAR max_health += 100 приведет к неизвестно чему. Если надо увеличть максимальное здоровье на 100, то данную команду нужно написать два раза.
055F: set_player $PLAYER_CHAR max_armour += 50 - тоже для бронижилета.
0109 player $PLAYER_CHAR money += 2000 - увеличить количесво денег у игрока на 2000. Чтобы уменьшить используйте эту же команду, но пишите не 2000, а -2000, то есть значение с минусом.
035F: set_actor $test_act armour_to 100 - установить актеру $test_act броню на 100%
0223: set_actor $test_act health_to 100 - то же для здоровья
Далее предлагаю разобраться с операторами перехода. Переходы бывают условные и безусловные, как в любом языке программирования. Безусловные переходы бывают двух типов - с возвратом и без возврата. Для перехода с возвратом используется команда 0050: gosub ЈЈ, а для безвозвратного перехода существует команда 0002: jump ЈЈ. Отличие возвратного перехода от безвозвратного в том, что при возвратном переходе скрипт, дойдя до строчки 0050: gosub ЈЈ будет выполнять все после объявления лэйбла до тех пор, пока скрипт не встретит команду 0051: return, после чего выполнение перейдет к строчке после 0050: gosub ЈЈ, а при безвозратном переходе после строчки 0002: jump ЈЈ действие перейдет к лэйблу и все команды после jump будут проигнорированы, даже если будет использоваться 0051: return. Условные переход всегда безвозвратные. Теперь, собственно говоря, перейдем к ним, к условным переходам. Как можно понять из название, этот переход осуществляется при выполнение какого либо условия, например если игрок находится рядом с какой-либо точкой или если какая-нибудь переменная равна определенному значению. Запись условия всегда начинается со строчки 00D6: if 0 - где 0 это количество условий минус 1, то есть для двух условий нужно писать 1, для трех - 2 и тд... Максимум условий может быть восемь, то есть 00D6: if 7. Все это означает что, например если два условия, то и первное и второе должно выполняться. Объясню на примере. Имеем условия
00D6: if 1
0038: $var_1 == 2
0038: $var_2 == 1
004D: jump_if_false ЈЈ
Так вот, если выполняется оба условия, то скрипт проигнорирует строку 004D: jump_if_false ЈЈ, и пойдет действие после этой строки. Кстати, забыл как раз рассказать про эту строку. Если условие(я) не выполняется то действие перейдет к лэйблу, который указан в этой команде, то есть в моем случае к . Ну так вот, если условия выполняются, то строка игнорируется. А что если нужно чтобы одна переменная равнялась 2, а другая не равнялась 1? Для этого нужно в опкоде первую цифру заменить на 8 и добавить перед условие слово NOT, то есть теперь наш пример будет выглядеть как
00D6: if 1
0038: $var_1 == 2
8038: NOT $var_2 == 1
004D: jump_if_false ЈЈ
Предпологаю, что теперь появился еще один вопрос: а если надо чтобы или одно условие выполнялось или другое? Для этого нужно цифру после if заменить на число условий плюс 19. Опять приведу пример
00D6: if 21
0038: $var_1 == 2
0038: $var_2 == 1
004D: jump_if_false ЈЈ
Теперь если или $var_1 будет равно 2 или $var_2 будет равно 1, строчка 004D: jump_if_false ЈЈ проигнорируется, а если оба условия не верны, то скрипт перейдет к . Тут тоже доступна конструкция с NOT. Замечу что минимальным количеством условий здесь является 2, то есть if 21, максимальное же прежнее - 8, то есть if 27.
Ну что ж, мы изучили почти все команды, с помощью которых можно написать датчик повреждений и спидометр. В нем есть команды, которые мы еще не прошли, но я попробую дать их точное описание. Ну что ж, приступим. Для начала создайте thread, где будет описан спидометр. Как это делать вы, надеюсь, уже знаете. Лэйбл спидометра назовем, например, spidometr. Полность код нашего спидометра будет выглядеть так (после ";" мои комментарии)
:spidometr ; обозначаем лэйбл
0001: wait 0 ms ; Нужно ставить эту строчку в начало тех лэйблов, куда мы будем переходить с помощью jump или gosub иначе игра будет виснуть.
00D6: if 0 ; начало блока условного перехода
00E0: player $PLAYER_CHAR driving ; проверяем, игрок в машине или нет
004D: jump_if_false ЈЈRemoveText ; если нет, то переходим к лэйблу RemoveText
03C1: $player_car = player $PLAYER_CHAR car ; присваиваем переменной $player_car идентификатор машины игрока
:ShowSpeed ; обозначаем лэйбл
0001: wait 0 ms ; выжидаем 0 милисекунд
00D6: if 0 ; начало блока условного перехода
0442: player $PLAYER_CHAR in_car $player_car ; проверяем, действительно ли игрок в своей машине. Лишняя проверка не помешает.
004D: jump_if_false ЈЈspidometr ; если нет - переходим к началу thread.
02E3: $car_speed = car $player_car speed ; заносим в переменную $car_speed скорость машины игрока.
0011: $car_speed *= 4.0 ; переводим ее в километры в час
008C: $car_speed = float_to_integer $car_speed ; переводим переменную $car_speed из дробного в целочисленный формат. Нужно для вывода на экран
04F7: unknown_status_text $car_speed 0 line 2 "SPEEDO" ; выводим на экран скорость авто игрока. Чуть ниже я расскажу об этой команде поподробнее
0002: jump ЈЈShowSpeed ; вернуться к началу расчета скорости. Если этого не сделать, то скорость покажется на долю секунды и изчезнет.
:RemoveText ; обозначаем лэйбл
0001: wait 0 ms ; выжидаем 0 милисекунд
0151: remove_status_text $car_speed ; удаляет с экрана текст, выводящий значение переменной $car_speed
0002: jump ЈЈspidometr ; возвращаемся к началу thread.
Теперь подробнее расскажу о команде 04F7: unknown_status_text $car_speed 0 line 0 "SPEEDO". Эта команда выводит текст в правый верхний угол, прямо под количесто здоровья и звездочки, показывающие уровень розыска. Разберем по параметрам.
$car_speed - показывает какое значение выводить.
цифра 0 после значения показывает тип текста (0 - просто текст, 1 - линия).
line 0 - показывает номер строки, всего их три (0, 1 и 2)
"SPEEDO" - имя ключа в файле american.gxt в котором лежит какой текст будет выведен перед значением скорости. Для спидометра туда лучше написать "кмч ~1~".
Текст на экран можно вообще выводить по разному. Вот сейчас и поговорим об этом. Для вывода текста есть много команд.
03E5: text_box "CUNTY" - это черный квадратик с текстом в углу появляется.
00BA: text_styled "CUNTY" 15000 ms 2 - это самый распостраненный способ вывода текста.
15000 - это время в милисекундах, которое текст на экране будет находиться.
2 - это вид текста. Он может быть разным шрифтом, размером, появляться в разных частях экрана. Поэкспериментируйте с этой цифрой, поймете.
CUNTY - ID текста в american.gxt
Часть 2
Также текст можно выводить с переменными значениями, т.е.
01E3: text_1number_styled "M_PASS" 5000 ms 1
На экран будет выведенно "MISSION PASSED $", чтоб это работало нужно в gxt запись добавлять указатели ~1~, ~2~, ~3~... и тд до 5 (или до 6, как в случае с styled текстами) параметров. Добавлять эти указатели нужно в то место, где вы хотите чтоб было переменное значение, та же запись M_PASS выглядит как "MISSION PASSED ~1~$". Если вы хотите чтобы появилась надпись "Ты за дней заработал денег, убив человек и взорвав машин" вам надо в gxt добавить запись со значением
"Ты за ~1~ дней заработал ~2~ денег, убив ~3~ человек и взорвав ~4~ машин"
а в скрипте написать:
036F: text 4numbers styled "" 5000 ms 2
Если вместо A,B,C,D используете переменные, то естественно нужно сначала присвоить этим переменным значения.
Бывают такие команды
0218: text_1number_styled - одно значение
036D: text_2numbers_styled - два
036E: text_3numbers_styled - три
036F: text_4numbers_styled - четыре
0370: text_5numbers_styled - пять
0371: text_5numbers_styled - шесть
Заметьте, что для пяти и шести слова одинаковые, а опкоды разные - это глюк билдера, по крайней мере версии 1.2
Далее, если вы хотите чтобы текста выводился как диалоги в игре, то нужно использовать команду
00BC: text_highpriority "" 5000 ms 1
5000 - время сколько текст будет на экране.
Ее тоже можно использовать с переменными значениями. Параметры там похожие что и в styled-текстах, поэтому напишу только опкоды этих команд
01E5: text_1number_highpriority - одно переменное значение
02FE: text_2numbers_highpriority - два
0300: text_3numbers_highpriority - три
0303: text_4numbers_highpriority - четыре
0306: text_5numbers_highpriority - пять
Теперь предлагаю вернуться к условным переходам и попробую описать все наиболее часто исползуемые условия.
002A: 0 >= $var - выполняется, если переменная $var меньше или равна нулю, естественно число можно менять. Только для целых чисел
001A: 10 > $var - выполняется, если переменная $var строго меньше цисла. Целое
0022: 100.0 > $var - то же для дробных значений
0032: 1228.7 >= $var - "меньше или равно" для дробных значений
001C: $var1 > $var2 - выполняется, если переменная $var1 больше $var2. Целое
0024: $var1 > $var2 - то же для дробей
0042: $var == 100.0 - выполняется, если дробная переменная $var равно 100.0
0020: $var > 180.0 - выполняется, если $var больше 180.0
003A: $var1 == $var2 - сравниваем целочисленные переменные
0018: $var > 19 - выполняется, если $var больше 19. Целое
0028: $var >= 23 - то же, только еще допускается равенство
0030: $var >= 1236.5 - нестрогое неравенство для дробей
0038: $var == 0 - если $var=0 - идем дальше. Кстати, хочу обратить ваше внимание на один нюанс. В переменной $ONMISSION всегда храниться информация о том, на миссии ли игрок или нет. Если 1 то на да, иначе нет. Это можно использовать, если надо, чтобы действие выполнялось только если игрок не занят миссией.
Так, с математикой закончили. Напомню что ко всем этим командам в опкоде первую цифру можно заменить на ноль и мы получим обратное условие. Перейдем к условиям с актерами, машинами и тд.
00ED: actor $actor 0 ()near_point_on_foot 1.8336 -938.0876 radius 1.0 1.0 - выполняется, если актер $actor находится рядок с точкой 1.8336 -938.0876 и при этом пешком. Последние две цифры - радиус от точки 1.8336 -938.0876.
0123: actor $actor spotted_player $PLAYER_CHAR - выполняется, если актер увидел игрока. Удобно для stealth-миссий
0448: actor $actor in_car $car - выполняется, если актер $actor находиться в машине $car, причем не важно: за рулем или как пассажир
00DF: actor $actor driving - а вот это уже если актер рулит машиной. Причем работает на любой машине. Для большего эффекта можно комбинировать с предыдущей командой.
00F3: actor $actor1 near_actor_on_foot $actor2 radius 5.0 5.0 0 - если актер рядом с другим актером на указанном радиусе и пешком
00A4: actor $actor 0 ()in_cube -991.591 261.036 7.775 -983.0 271.96 11.506 - если актер в кубе с указанными координатами и размерами. Как распологаются координаты я не знаю, так что экспериментируйте
0100: actor $actor near_point_in_car -649.6716 -1590.727 40.0 radius 5.0 5.0 5.0 sphere 0 - если актер на машине рядом с указанной точкой. После sphere - показывать ли в точке маркер?
00DD: actor $actor driving_vehicle_type #ANGEL - если актер ведет машину определенного типа
0102: actor $actor stopped_near_point_on_foot -693.58 1213.18 23.16 radius 1.0 1.0 2.0 sphere 0 - если актер остановился пешком возле точки. Остальные параметры, думаю, уже ясны
0118: actor $actor dead - если актер мертв
031D: actor $actor hit_by_weapon 23 - если актер раннен определенным типом оружия. Описание типов файле weapon_numbers.txt
0184: actor $actor health >= 95 - проверка здоровья актера
00FF: actor $actor 0 ()near_point_on_foot -991.591 261.036 7.775 radius 2.0 2.0 2.0 - если актер рядом с точкой пешком
0320: actor $actor in_range_of_player $PLAYER_CHAR - если актер в поле видимости игрока
0101: actor $actor stopped_near_point -991.591 261.036 7.775 radius 3.0 3.0 1.5 sphere 0 - если актер остановился рядом с точкой, причем не важно пешком или на машине
00F0: actor $actor stopped 0 ()near_point_on_foot 461.4445 -495.2143 radius 2.0 2.0 - то же самое, только уточняется что пешком
00F2: actor $actor1 near_actor $actor2 radius 100.0 100.0 0 - тоже проверка на "близость" актеров, только неважно на машине или пешком
00EE: actor $actor1 0 ()near_point_in_car 461.4445 -495.2143 radius 3.0 3.0 - если актер рядом с точкой и на машине
0203: actor $actor near_car_on_foot $car radius 35.0 35.0 unknown 0 - если актер рядом с машиной. Последний параметр неизвестен
0205: actor $actor near_car $car radius 7.0 7.0 6.0 unknown 0 - то же, только для 3д-координат да еще и пешком
00FE: actor $actor 0 ()near_point 427.6 -584.7 10.6 radius 1.0 1.0 5.0 - если актер рядом с точкой, причем неважно пешком или нет
Перейдем к машинам:
01C1: car $car stopped - если машина стоит
0137: car $car id == #VOODOO - если машина - VooDoo, естественно, #VOODOO можно менять
01F3: car $car airborne - если машина летит
020D: car $car flipped - если машина крутиться
0119: car $car wrecked - если машина разбилась, то есть ее health = 0
02BF: car $car sunk - если машина тонет. Причем интересная вещь. Приоритет у sunk больше чем у wrecked
01AF: car $car 0 ()near_point 95.3 -1468.3 9.5 radius 1.5 1.5 3.0 - машина возле точки
0185: car $car health >= 269 - проверка здоровья машины
016B: fading
0329: garage $garage respray_done - если гараж - Pay'n'Spray и машина перекрашена. Подробнее о гаражах можно будет прочитать позже, а пока запомниет эту и две нижеописанных команды
03D4: garage $garege contains_neededcar 1 - если в гараже стоит нужная машина
03B1: garage $garage door_closed - если дверь гаража закрыта
00E1: key_pressed 0 19 - если нажата клавиша. На клавишу указывает последняя цифра. Может быть:
Число Пешком В машине
--------------------------------------------------------------
2 повороты Турель влево/вправо
3 Турель вверх/вниз
4 Действие Смена радио
5 Пред. оружие влево/смотреть назад
6 Прицеливание ручник
7 След. оружие смотреть вправо/назад
8 вперед
9 назад
10 шаг влево поворот влево
11 шаг в право поворот влево
13 смена камеры смена камеры
14 прыжок тормоз/задний ход
15 в машину из машины (Enter)
16 спринт Газ
17 атака огонь
18 присесть гудок
19 смотреть назад Подмиссия
Теперь перейдем к условиям связанными с игроком. Некоторые из них повторяют условия актеров, так что для похожих я не буду писать описание.
0256: player $PLAYER_CHAR defined - вообщем существует игрок? Используется, например, при сохранении, когда id игрока стирается и чтобы игра не повилса используется это условие
00F6: player $PLAYER_CHAR 0 ()near_point_on_foot 95.3 -1468.3 9.5 radius 1.4 1.8 1.5
00F5: player $PLAYER_CHAR 0 ()near_point -926.8099 -327.8378 13.3894 radius 4.0 4.0 4.0
010A: player $PLAYER_CHAR money > 1000 - проверка количества денег
00E9: player $PLAYER_CHAR 0 ()near_actor $actor radius 100.0 100.0
00DE: player $PLAYER_CHAR driving_vehicle_type #HUNTER
0500: player $PLAYER_CHAR skin == "PLAYER6" - если моделью игрока является указанная модель
00F9: player $PLAYER_CHAR stopped 0 ()near_point_on_foot -926.8099 -327.8378 13.3894 radius 1.0 1.0 2.0
00F7: player $PLAYER_CHAR 0 ()near_point_in_car -926.8099 -327.8378 13.3894 radius 2.0 2.0 2.0
02DE: player $PLAYER_CHAR driving_taxi_vehicle - если игрок в такси любого типа (просто такси, Кэби, Кауфман Кэб)
00E3: player $PLAYER_CHAR 0 ()near_point -1235.1 -1235.7 radius 4.0 4.0
0443: player $PLAYER_CHAR in_a_car
00E0: player $PLAYER_CHAR driving
047E: player $PLAYER_CHAR driving_a_motorbike - если игрок сидит на любом мотоцикле
02D7: player $PLAYER_CHAR currentweapon == 22 - проверяет текущее оружие игрока. Номера все оттуда же
00FA: player $PLAYER_CHAR stopped 0 ()near_point_in_car 240.4 -1280.2 10.0 radius 4.0 4.0 3.0
0490: player $PLAYER_CHAR has_weapon 18 - есть ли у игрока такое оружие?
0241: player $PLAYER_CHAR in_remote_mode - игрок за пультом управление машинкой, самолетиком и тп?
010F: player $PLAYER_CHAR wanted_level > 0 - проверка уровня розыска игрока. 1 - одна звезда, 2 - естественно, две звезды и тд
01FC: player $PLAYER_CHAR near_car $car radius 30.0 30.0 0
00FC: player $PLAYER_CHAR 0 ()near_actor $car on_foot radius 3.0 3.0 2.0
0442: player $PLAYER_CHAR in_car $car
00EB: player $PLAYER_CHAR 0 ()near_actor_in_car $car radius 50.0 50.0
01FE: player $PLAYER_CHAR near_car_in_car $car radius 20.0 20.0 0 - рядом с машиной да еще и сам на машине
0112: wasted_or_busted - игрок умер или арестован
0122: player $PLAYER_CHAR pressing_horn - игрок гудит
Вот вроде бы как и все... Статейка получилась больше чем обычно. Вопросы как всегда на форум.