Оглавление

Соавторы

Все главы не являющиеся ссылками, содержаться на странице вызываемой ближайшей верхней ссылкой !!! - работа завершена, стадия поиска ошибок *** - над разделом идет работа ??? - работа над разделом еще не началась(выложен черновик) /? - в разделе есть, вопросы по которым данные отсутствуют
Оглавление | Статус | Дата внесения последних изменений
Вступление | !!! | 17/01/2005
Что такое – навигационный скрипт? | !!! | 24/01/2005
Запасемся инструментом. | !!! | 26/01/2005
Синтаксис команд HC. | !!! | 24/01/2005
В каком редакторе пишется НС, и где его взять ? | !!! | 21/01/2005
Какие бывают скрипты? | !!! | 17/01/2005
Описание редактора скриптов "X2 The Threat" | !!! | 21/01/2005
Редактор скриптов | !!! | 24/01/2005
Reinit Script Caches | !!! | 24/01/2005
Script Debugging | !!! | 24/01/2005
Clear Debug Messages | !!! | 17/01/2005
Script Debugger Menu | !!! | 24/01/2005
Global Script Tasks | !!! | 17/01/2005
Просмотр и редактирование НС | !!! | 18/01/2005
Просмотр скриптов из папки /scripts | !!! | 18/01/2005
Просмотр упакованных скриптов (PCK) | !!! | 18/01/2005
Просмотр сторонних скриптов | !!! | 18/01/2005
Редактирование скриптов | !!! | 18/01/2005
Структура НС | !!! | 18/01/2005
Имя скрипта (Script) | !!! | 18/01/2005
Версия (Version) | !!! | 24/01/2005
Описание (discription) | !!! | 18/01/2005
Аргументы (Arguments) | !!! | 18/01/2005
Исходный текст (Source text) | !!! | 18/01/2005
Цифровая подпись навигационного скрипта | !!! | 21/01/2005
Введение в скриптописание Х2 | *** | 30/01/2005
Переменные. Типы переменных | !!! | 17/01/2005
Массивы. | !!! | 21/10/005
Константы | !!! | 31/01/2005
Операции | !!! | 30/01/2005
Операторы условного перехода | !!! | 24/01/2005
Операторы безусловного перехода | !!! | 24/01/2005
Циклы | !!! | 11/03/2005
Интерпритатор скриптовых команд (ScE) | *** |
Многозадачность | !!! | 22/03/2005
Локальные скрипты, глобальные скрипты | !!! | 17/01/2005
Задачи, стеки, приоритеты | !!! | 22/03/2005
"Волшебные" номера задач | !!! | 22/03/2005
Прерывания | !!! | 6/04/2005
Сигналы | !!! | 22/08/2005
BBS-Engine генерация и обработка досок объявлений | *** | 14/05/2005
Организация AL Engine (Искусственная жизнь) | !!! | 22/09/2005
Языковые файлы XML в Х2 | !!! | 30/01/2005
Что такое языковой файл | !!! | 19/01/2005
Как делается языковой файл и при помощи какой программы | !!! | 19/01/2005
Использование пользовательских языковых файлов при работе с командным меню | !!! | 19/01/2005
Инициализация языкового файла | !!! | 19/01/2005
Пользовательские языковые файлы для создания текстовых шаблонов | !!! | 19/01/2005
Использование тег'ов в языковых файлах | !!! | 26/01/2005
Спецтег ссылка | !!! | 15/11/2005
Особенности некоторых команд | *** | 27/01/2005
Особенности навигационных команд (FLY). Возвращаемый код FLRET | !!! | 27/01/2005
Организация глобального поиска объектов. Флаги поиска (Find). | !!! | 27/01/2005
Использование информативных команд set command, set destination, set target и т.п. | !!! | 24/04/2005
Команды ScE "X2 The Threat" (полный список команд) | !!! | 6/02/2005
Общие команды | *** | 21/10/2005
Команды исполнения | !!! | 21/10/2005
Вызов скриптов | !!! | 17/01/2005
Массивы | !!! | 21/10/2005
Аудио команды | !!! | 7/09/2005
Команды для работы с бортовым журналом | !!! | 26/01/2005
Навигационные команды ( Fly commands ) | !!! | 19/03/2005
Торговые команды ( Trade commands ) | !!! | 21/10/2005
Для кораблей (Ships) | !!! | 21/10/2005
Для станций (Stations) | !!! | 13/02/2005
Для кораблей и станций (Ships and Stations) | !!! | 13/02/2005
Работа с объектами ( General object commands ) | !!! | 21/10/2005
Команды работы с галактикой и секторами ( Universe and sector commands ) | !!! | 7/09/2005
Советы бывалого скриптописателя | *** | 26/01/2005
Как выходить в Windows из игры. | !!! | 26/01/2005
Переименовываем файл скрипта | !!! | 26/01/2005
Обходим ограничение редактора ScE на использование русской раскладки | !!! | 26/01/2005
Приложение | *** |
Точки входа и флаги состояния сюжетной линии | !!! | 9/04/2005
Симплы "X2 The Threat" | !!! | 17/01/2005
Голосовые Симплы | !!! | 22/01/2005
Имена секторов галактики Х2 (голосовые симплы) | !!! | 22/01/2005
Латинские и греческие буквы (page 9 & 12) (голосовые симплы) | !!! | 08/03/2005
Фразы бортового компьютера (голосовые симплы) | !!! | 08/04/2005
Названия фабрик, товаров, объектов (голосовые симплы) | !!! | 9/04/2005
Иерархическая схема классов объектов (схема) | !!! | 15/02/2005
Сводная таблица типов и подтипов товаров и объектов | !!! | 11/03/2005
Описание типов астероидов (описание, скрины) | !!! | 17/02/2005
Описание типов туманностей (описание, скрины) | !!! | 19/02/2005
Описание типов солнц (скрины) | !!! | 24/02/2005
Описание типов планет (визуальные образы) | !!! | 24/02/2005
Описание специальных объектов (инструкции create special object) | !!! | 11/03/2005
Визуальные образы пилотов кораблей (для команды set pilot speaker) | !!! | 07/03/2005
Практикум |  |
Создаем новую команду в командном меню | !!! | 14/08/2005
Создаем новый товар и размещаем его на станциях | *** | 14/05/2005
Статьи пилотов (Коментарий к содержимому раздела) | *** | 28/01/2005
Station Manager (автор: пилот aka ANS) | !!! | 28/01/2005
Скрипт захвата астероидов "xt.dp.asteroidcollector" (автор: Антон Поляков aka XenonTomb) | !!! | 31/01/2005
"Учимся писать скрипты" разбираем скрипт Корабль-Склад (автор: Антон Поляков aka XenonTomb) | !!! | 3/02/2005
Статьи пилотов о модинге |  |
Создаем свой корабль из стандартных частей. (автор ZAV) | !!! | 21/09/2005
Моддинг: связь TShips и моделей кораблей (автор Breeze) | !!! | 21/09/2005


Организация AL Engine

v Организация AL Engine (Искусственная жизнь)

AL Engine разрабатывалась для управления скриптами создающими игровой антураж в Х2-Вселенной, такими как корабли патрулирующие родные сектора, лайнеры везущие пассажиров, ударные группы ведущие мониторинг Президентского Рубежа и т.д. Использование AL Engine значительно облегчает организацию работы AL скриптов управляющих этими процессами, и позволяет в фоновом режиме производить их запуск, остановку, инициализацию и прочие действия. А сам движок Х2 позволяет оперативно отказаться или наоборот подключить нужный AL plugin используя меню настройки искусственной жизни.

Все AL скрипты находящиеся под управлением AL Engine должны быть устроены по определенной схеме. Строится она из последовательности состоящей из трех основных скриптов каждый из которых выполняет определенную задачу.

1. Регистрационный скрипт – этот скрипт производит необходимую регистрацию AL Plugin’a в системе. Сообщая ей какой скрипт необходимо взять под управление AL Engine. Запускается автоматически.

2. Контроллер событий – этот скрипт обеспечивает соответствующую реакцию на переданные от AL Engine флаги событий и указывает какие действия необходимо произвести в ответ на них.

3. Скрипт таймер – это основной скрипт осуществляющий всю работу с AL объектом. Этот скрипт вызывается системой периодически, в зависимости от действий игрока и предварительной настройки AL Engine сделанной в «Контролере событий».

Обратите внимание на то, что любой скрипт из этой группы работает в системе как глобальный, так что в них не допустимо использовать константы [THIS], [OWNER], [SECTOR] и подобные, т.к. они привязаны к объекту на котором выполняется скрипт. А глобальный как вам известно, не имеет привязки к объектам.

Регистрационный скрипт

Это самый простой скрипт из группы AL Engine скриптов. Его задача зарегистрировать plugin в движке AL Engine. Обязательным условием является определенный формат имени. Имя должно начинаться с al.plugin…, далее идет имя самого plugin’a. Это имя сообщает ScE что данный файл следует загрузить автоматически. Учтите что AL plugin загружаются самыми последними, даже не после загрузки всех init и setup скриптов, а спустя некоторое время. Для удобства, имена для всех остальных скриптов относящихся к вашему AL plugins, именуйте например вот так al.<ваш ник>.mainPlug, а регистрационные скрипты, например:

!al.plugin.tpliners или al.plugin.racepatrol .

Дальнейшее рассмотрение принципов организации AL plugin на встроенном в игру AL Plugin «TP Лайнеров» Вот регистрационный файл из этого пакета:

Script !al.plugin.tpliners

Version: 1
for Script Engine Version: 25

Description

AL plugin TP Liners

Arguments

Source Text

 001
 002   al engine: register script='!al.tpliners.main'
 003
 004   return null

signed

Здесь наглядно видна простота его устройства, всего одна строка регистрирующая !al.tpliners.main как AL Plugin. Получив эту команду AL Engine зарегистрирует данный AL plugin и запустит соответствующий скрипт с флагом ‘init’ или ‘reinit’ (от чего зависит флаг см. далее), а после инициализации сразу с флагом ‘timer’.

Контроллер событий. (Event Handler)

В скрипте контроллера событий должно быть предусмотрено два строковых аргумента значения которым будут переданы самой AL Engine. Первый аргумент это уникальный идентификатор plugin’a по которому AL Engine будет обращаться к нему (как идентификатор AL Engine использует имя скрипта «контроллера событий»). Второй аргумент это флаг типа событий. Возможные варианты флагов событий прописаны в самой AL Engine. Все возможные варианты приведены в таблице ниже:

Событие | Описание
‘init’ | Происходит при старте новой игры или если AL Engine зарегистрировала первый запуск данного plugina’a.
'reinit' | Происходит при загрузке сохраненной игры.
'start' | Происходит если игрок выбрал опцию «Вкл.» в меню настройки искусственной жизни.
'stop' | Происходит если игрок выбрал опцию «Выкл.» в меню настройки искусственной жизни.
'isenabled' | Происходит когда формируется меню настройки искусственной жизни. Для чего нужен этот описатель см. далее.
‘timer’ | Происходим каждый раз по истечении временного интервала установленного инструкцией set plugin timer interval. Служит для определения частоты запуска данного AL plugin.

Прежде всего о том как работает AL Engine в общих чертах. Все элементарно просто, вся ее функция заключается в периодическом вызове скриптов зарегистрированных как AL plugin и формировании соответствующих флагов-событий. И обязательно запомните следующее, сама по себе AL Engine понятия не имеет выполняется в данный момент какой либо plugin или нет. Это очень важный факт, т.к. обеспечивать правильные реакции вашего plugin’на флаги-событий придется вам самим, используя разные вариации разного рода флагов и переменных.

Так как AL Engine не ведет контроля за тем активен в данный момент plugin или нет, рассмотрим почему необходим и как мы можем использовать флаг-события “isenabled”. Этот флаг AL Engine выставляет для всех зарегистрированных plugin (для зарегистрированных, а не для активных), в момент когда игрок открывает меню настройки искусственной жизни. Так же в этот момент стартуют контроллеры событий всех зарегистрированных plugin. Задача контроллера событий, при обработке флага-события «isenabled» вернуть системе флаг текущего состояния plugin, т.е. активен он в данный момент или нет. И в зависимости от того, что вернул контроллер система сформирует соответствующее состояние выключателя для данного plugin в меню. Система воспринимает значения как [TRUE] – plugin активен и выполняется, [FALSE] – plugin отключен, но учтите что несмотря на это AL Engine продолжит производить его запуск с флагом «timer» по истечении каждого временного отрезка установленного командой al engine: set plugin <Var/String> timer interval to <Var/Number> s. Заметьте что интервал выставляется не в привычных уже миллисекундах, а в секундах.

Условия формирование флага-события «timer» очевидна. После инициализации plugin, а именно тогда происходит назначение временного интервала для данного plugin, будет происходить вызов контроллера событий с установленным флагом «timer» по истечении назначенного временного отрезка. Вызов будет происходить и в случае если plugin находится в состоянии остановки, и здесь вы сами должны обеспечить правильное поведение вашего скрипта-plugin.

Флаги событий “stop”, “start” формируются когда игрок устанавливает выключатель AL plugin в соответствующее положение. Установив выключатель, и нажав <Enter> игрок дает указание AL Engine произвести запуск скрипта контроллера событий с выставлением ему соответствующего флага.

Значение флагов “init” и “reinit” понятно из описания в таблице, первый выставляется при старте новой игры или при первом запуске AL plugin, а второй при загрузке сохраненной игры.

Теперь, когда мы рассмотрели сам принцип работы AL Engine и флагов-событий, приступим к рассмотрению того как это организовать в вашем скрипте. Самый удобный способ добиться четкого взаимодействия частей нашего plugin это обеспечить между ними обмен необходимыми данными. Сделать это можно по средствам использования глобальных переменных. Может оказаться так, что объем передаваемых данных может быть очень большим и создавать такое количество глобальных переменных крайне не удобно. Решением этого является использование массива, записанного в глобальную переменную. На самом деле ScE не хранит в переменной сам массив, а только указатель (pointer) на область памяти где размещаются эти данные, что в нашей ситуации более удобно, так как не придется перекидывать массив данных от одного скрипта к другому, достаточно передать этот пойнтер. Еще, есть некоторая договоренность о формате этого массива, которая облегчит работу с вашим plugin другим скриптописателям, но она не обязательна, и заключается в следующем:

1. Первым значением в массиве, индекс [0], стоит версия вашего AL plugin, если вы делаете универсальный и самообновляющийся скрипт (желательно чтобы таким был любой скрипт), то наличие в переменной версии будет очень полезно.

2. Второе значение это флаг состояния AL plugin, [TRUE/FALSE] индекс [1]

Остальные значения используются на ваше усмотрение. Вы не обязаны следовать этому правилу, но это определенный шаг к стандартизации дополнительных AL plugin, и значительное облегчение для тех кто будет разбираться с работой вашего скрипта.

И так, мы рассмотрели основные теоретические аспекты, и можем перейти к практическому разбору AL plugin. Для примера я выбрал встроенный в игру AL plugin Межгалактических лайнеров, и так рассмотрим его:

Script !al.tpliners.main

Version: 1
for Script Engine Version: 25

Description

AL plugin main tp liners

Arguments

  • 1: plugin.ID , Var/String , 'plugin ID'
  • 2: plugin.Event , Var/String , 'plugin event'

Этот скрипт был за зарегистрирован в AL Engine при помощи регистрационного файла !al.plugin.tpliners в момент старта новой игры или загрузки сохраненной. После регистрации движок AL Engine запустил скрипт контроллер событий !al.tpliners.main с флагом “init”, “reinit” соответственно, поместив их во второй аргумент plugin.Event. В первый аргумент было помещено имя нашего plugin. Далее за обработку полученных данных берется сам контроллер событий.

Source Text

 001
 002   * global variable stores plugin state und data
 003   $plugin.Vars = get global variable: name=$plugin.ID
 004   if not $plugin.Vars
 005   * setup new data structure and init it
 006    $plugin.Vars =  array alloc: size=32
 007    set global variable: name=$plugin.ID value=$plugin.Vars
 008   * data structure version
 009    $plugin.Vars[0] = 0
 010   * plugin enabled
 011    $plugin.Vars[1] = [TRUE]
 012   * other elements store ships, created via timer event
 013   end

001-003 Получаем значение глобальной переменной, одноименной нашему plugin, название было передано в переменную-аргумент $plugin.ID самой AL Engine.

004-006 Если такой переменной не существует (возвращенное значение null), то заготавливаем нужную нам матрицу, то есть массив содержащий необходимое нам количество элементов.

007 Создаем соответствующую глобальную переменную и помещаем в нее указатель (пойнтер) на пока еще пустой массив. Теперь передавая пойнтер другим скриптам, мы сможем использовать и изменять данные в этом массиве.

008-013 В согласии с негласными правилами помещаем в соответствующие ячейки версию скрипта (в данном примере автор не использовал команду <RetVar>=get script version, вероятно для обеспечения совместимости скрипта с предыдущими версиями ScE, до 1.4, где эта команда отсутствовала и прибегнул к собственной нумерации. Но вам настоятельно рекомендую пользоваться этой командой.). Итак, в ячейку [0] помещается версия AL plugin, а в [1] флаг текущего состояния выставленный [TRUE].

Далее начинаем анализ выставленных флагов событий $plugin.Event.

014
 015   * handle plugin events
 016
 017   if $plugin.Event == 'init' OR $plugin.Event == 'reinit'
 018    $desc = sprintf: pageid=2023 textid=200, null, null, null, null, null
 019    al engine: set plugin $plugin.ID description to $desc
 020    $interval = random value from 50 to 70 - 1
 021    al engine: set plugin $plugin.ID timer interval to $interval s

В этих строках производится обработка, в случае выставления системой любого из флагов инициализации. То есть сюда мы попадаем если AL Engine выставила один из флагов “init” или “reinit” а это возможно только в том случае, если была начата новая игра или загружена сохраненная.

017 Проверяем соответствие флагов. Тип данных у флагов <string> и вводятся они как текст.

018-019 Получаем из языкового файла текст, и устанавливаем его как дескриптор данного AL plugin. Дескриптор будет отражаться в меню настройки AL в соответствующей данному plugin строке. В нашем случае это текст «Движение лайнеров по вселенной Х» (перевод ЕГ).

020-021 Получаем случайный интервал в пределах 50 – 70 секунд, и указываем его AL Engine как интервал вызова нашего AL plugin.

022
 023   else if $plugin.Event == 'isenabled'
 024    $enabled = $plugin.Vars[1]
 025    return $enabled

Если при старте plugin’a был выставлен флаг “isenabled”, то это означает, что в данный момент формируется меню настройки AL и система запрашивает у скрипта текущее состояние AL plugin, так как сама система не осуществляет за ним постоянного контроля.

023 проверка на соответствие флага.

024 Возвращаем нужное нам значение в переменную $enabled из массива $plugin.Vars.

025 Возвращаем это значение движку, который в свою очередь при формировании меню выставит выключатель в положение соответствующее этому значению.

026
 027   else if $plugin.Event == 'start'
 028    $plugin.Vars[1] = [TRUE]
 029
 030   else if $plugin.Event == 'stop'
 031    $plugin.Vars[1] = [FALSE]

026 -031 Если игрок изменил значение выключателя в меню настройки AL, то после нажатия “Enter” AL Engine запускает наш контроллер установив соответствующий флаг, а скрипт в свою очередь производит соответствующие изменения в [1] ячейке массива.

032
 033   else if $plugin.Event == 'timer'
 034 @  = [THIS] ->call script '!al.tpliners.event.timer' :plugin  ID=$plugin.ID plugin data=$plugin.Vars
 035   end
 036
 037   return null

И обработка последнего из возможных флагов-событий, флаг ‘timer’. Получив этот флаг, контроллер нашего AL plugin безоговорочно стартует основной скрипт управления AL объектами !al.tpliners.event.timer передав ему в виде аргументов имя нашего AL plugin, оно также соответствует имени глобальной переменной содержащей пойнтер на рабочий массив данных, и сам пойнтер.

Небольшая информационная заметка. Вы наверное заметили, что обработав флаги и изменив переменные мы не сохраняем их в глобальной переменной, а просто изменяем их в массиве $plugin.Vars. Не делается это по тому, что наша переменная $plugin.Vars содержит указатель на туже область памяти, что и глобальная переменная. И соответственно, нам достаточно исправить значение по пойнтеру содержащемуся в переменной $plugin.Vars, как эти значении становятся доступны любому скрипту обратившемуся к этой области памяти, достаточно передать через глобальную переменную этот пойнтер.

Скрипт таймер

Назначение этого скрипта, это непосредственно реализация самой идеи вашего AL plugin, создание и управление AL объектами. Именно этот скрипт создаст задуманные вами объекты, назначит им соответствующие команды, проверит живы ли они, и произведет воссоздание уничтоженных. Мы продолжим рассмотрение на основе того же AL plugin управляющего летающими по галактике лайнерами.

Основные задачи на нашего скрипта !al.tpliners.event.timer, это не допустить своего собственного запуска этого если игрок отключил это AL plugin в меню настройки AL, не забывайте что AL Engine независимо от этого будет производить запуск этого скрипта с флагом ‘timer’. А если скрипт находиться в активном состоянии, то произвести проверку уже созданных лайнеров, отдать новые команды живым и воссоздать и отправить новые вместо убитых. Подробно рассматривать процесс воссоздания и контроля мы не будем. Рассмотрим только принцип блокировки запуска в случае отключения этого AL plugin.

Script !al.tpliners.event.timer

Version: 1
for Script Engine Version: 25

Description

AL plugin tp liners timer event

Arguments

  • 1: plugin.ID , Var/String , 'plugin ID'
  • 2: plugin.Vars , Value , 'plugin data'

Source Text

 001
 002   * read state data
 003   $plugin.Enabled = $plugin.Vars[1]
 004
 005   skip if $plugin.Enabled
 006    goto label exit
 007
 008   * check ships

...

Здесь находятся процедуры проверки и восстановления убитых лайнеров, их вы можете посмотреть открыв этот файл у себя на компьютере.

...
 062   exit:
 063   * store state data
 064
 065   return null

Из предыдущего скрипта видно какие аргументы мы передаем текущему. Это строка с именем скрипта и пойнтер массива с флагами. Вся интересующая нас проверка осуществляется в первых шести строчках далее идет код процедур проверок и респауна лайнеров, его рассматривать мы не будем. А сома блокировка запуска очень проста:

003 Получаем значение флага состояния из массива.

005-006 Проверка состояния переменной и если флаг [TRUE] продолжаем выполнять скрипт, в противном случае переход на строку 062 и выход, до следующего запуска по ‘timer’ или изменения флага через меню AL.

Теперь вы знаете как создать и правильно организовать работу AL Engine, для того чтобы узнать больше рассмотрите работу других AL плагинов идущих с игрой. Мое мнение, что чем более насыщена жизнь в Х2-Вселенной разного рода интересными вещами тем интереснее играть.


Соавторы проекта

Данный проект построен на первоисточниках:

  • Энциклопедия по Х2 Version 1.3 Copyright by Dimaxx® & Pegasus®, часть Скрипты от Кузьмин Денис aka MAD_Kuzia

  • Переводе пособия Курта Физнера "The X2 MSCI Programmer Handbook" Версии 1.1

  • Статьи из конференции на сайте Elite-Games (http://www.elite-games.ru)

  • Форум на Эгософт.

Эта страница содержит информацию об соавторах данного проекта. К сожалению на сегодняшний день почти все указанные здесь пилоты работают заочно. Под этим я подразумеваю, использование мной статей, комментариев, описаний и т.п.информации размещенной этими пилотами в конференции на EliteGames, без прямого их участия в этом поекте.

Ниже я размещаю список aka пилотов, и названия их статьей использованных мной:

Имя Материал
akm

Полностью описать вклад этого пилота тяжело, т.к. на основе постов akm взятых в конференции на ЕГ построено не менее четверти этого проекта .

  • Описание команд связанных с запуском и прерыванием скриптов
  • Ссылки на ресурсы по скриптописанию в Х2.
ANS
  • Главы "Многозадачность", "Семейство команд Wait, Fly", "Волшебные номера задач", "Задачи, стеки, приоритеты","Локальные скрипты, глобальные скрипты".
  • Статья "Разбор скрипта Station Manager"
  • Информация о тегах и спецсимволах
Grey Wolf
  • Дополнение в главу "Имя скрипта"
Khaak-Year
  • Ссылка на инфо о подписи скрипта на Egosoft
XenonTomb

Поляков Антон

  • Статья-описание скрипта xt.dp.asteroidcollector (захват астероида)
  • "Учимся писать скрипты" разбираем скрипт Корабль-Склад
  • Коментарии, дополнения к описаниям команд
  • Помощь в описании Типов и Подтипов товаров и объектов
  • Статья "Принципы использования циклов"
AlexYar
  • Исправление ошибок. Коментарии к командам. Большое количество дополнений
Krom
  • Коментарии и дополнения.


Использование информационных команд

v Использование информационных команд (из группы «навигационные команды».

Когда ваши корабли выполняют какую либо встроенную команду (покупают товар или атакуют кого то), то открыв информационный экран вашего корабля вы увидите, что выполняемые кораблем в данный момент действия описываются в соответствующей строке экрана (также текущая команда отражается в меню собственности). Например: корабль получил команду «Атаковать Кремниедобывающую шахту альфа»

Информационный экран:

Меню собственности:

В строке команда отобразилась «Атаковать…Кремниедобывающая шахта альфа», сообщает о том, что в данный момент исполняется скрипт связанный с командой в меню «Атаковать». В строке действие отображено какое действие выполняет корабль в данный момент, фактически какая навигационная команда выполняется в данный момент. Скрипт команды «Атаковать» состоит из множества команд в том числе Навигационных команд, в частности речь идет о навигационных командах помеченных знаком «@» (за исключением команды turn turret), именно эти команды при выполнении помещают комментарий действий в пункт «Действия» информационного экрана. Также, в инфо корабля при использовании разных команд из командного меню могут присутствовать пункты «Назначение» «Атакуется».

Особенность информативных команд заключается в том, что они не влияют на поведение корабля, а имеют исключительно информационный характер. Это говорит о том что при помощи некого скрипта, можно отправить корабль в одно место, а информационной командой указать другое. В итоге корабль полетит туда куда ему было указанно лететь командой из группы управляющих команд, а в информационном меню будет отращена информация указанная информационными командами. Далее в этой главе будет рассмотрено как сделать свой скрипт информативным, то есть обеспечить отображение служебной информации в инфо корабля во время его исполнения.

Информативные команды можно условно разделить на несколько групп:

1. Общие информативные команды – это те команды, которые будут отражать информацию в течении выполнения всего скрипта или до другой информативной команды.

2. Условные информативные команды – это те команды, что отразят информацию на информационном экране только в том случае, если будет выполняться соответствующее ей действие.

давайте начнем по порядку.

Общие информативные команды.

Прежде всего рассмотрим работу общих информативных команд. Начнем с команды set command. Эта команда отображает в информационном окне текст напротив заголовка «Команда». Отображаемый текст связан непосредственно с ней и берется из языкового файла (page2010). Не все команды имеющиеся в ScE Х2 доступны редактору. В таблице собраны все встроенные команды присутствующие в игре и связанный с ними текст, в последней колонке указанно имеет ли редактор доступ к команде:

Команда | Связанный текст | Дост.
COMMAND_NONE | Нет команд | Да
COMMAND_RETURN_HOME | Вернуться на базу | Да
COMMAND_ATTACK_NEAREST | Атаковать ближайшего неприятеля | Да
COMMAND_ATTACK_TARGET | Атаковать мою цель | Да
COMMAND_PROTECT | Защищать... | Да
COMMAND_FOLLOW | Следовать... | Да
COMMAND_STAY | Оставаться на месте | Да
COMMAND_DOCKAT | Стыковка к... | Да
COMMAND_ATTACK_SAME | Атаковать цель... | Да
COMMAND_GET_WARE | Покупать товар... | Да
COMMAND_GET_WARE_BEST | Покупать товар по лучшей цене... | Да
COMMAND_SET_HOME | Установка базы | Нет
COMMAND_MOVE_SECTOR | Лететь в сектор... | Да
COMMAND_ATTACK | Атаковать... | Да
COMMAND_KILL_ENEMIES_AND_LAND | Уничтожить всех врагов и стыковаться | Да
COMMAND_KILL_ENEMIES | Уничтожить всех врагов | Да
COMMAND_COMBAT | Бой по умолчанию | Нет
COMMAND_IDLE | Ожидать | Да
COMMAND_INVASION | Вторгаться... | Да
COMMAND_MOVE_POS | Лететь на позицию... | Да
COMMAND_ACTION | Действие по умолчанию | Да
COMMAND_TRADE | Торговля | Нет
COMMAND_ATTACK_RETURN | Атаковать врага и стыковаться... | Да
COMMAND_COLLECT_WARE | Подбирать контейнеры... | Да
COMMAND_PATROL | Патрулировать сектор | Да
COMMAND_KILL_ENEMIES_RANGE | Атаковать врагов в радиусе... | Да
COMMAND_PREACH | Проповедовать | Да
COMMAND_SELL_WARE | Продавать товар... | Да
COMMAND_SELL_WARE_BEST | Продавать товар по лучшей цене... | Да
COMMAND_COLLECT_FLYINGWARES | Подбирать контейнеры в секторе... | Да
COMMAND_PIRATE_PLUNDERSHIPS | Грабить корабли в секторе... | Да
COMMAND_TURRET_KILL_ENEMIES | Турели уничтожать врагов... | Да
COMMAND_TURRET_ATTACK_TARGET | Турели атаковать мою цель | Да
COMMAND_TURRET_MISSILE_DEFENCE | Турели сбивать ракеты | Да
COMMAND_TURRET_PROTECT | Турели защищать корабль | Да

Помимо встроенных команд, в Х2 присутствуют несколько групп команд свободных для использования (Trade, Special, Custom и т.п.). Если аргументом для команды set command выбрать любую из свободных команд из этой группы, то напротив заголовка команда отразится надпись “unknown Command!”, происходит это из-за того, что в основном языковом файле на странице 2010 вообще отсутствует связанный с этой командой текст. Текст связанный с этими командами может быть изменен или добавлен, как это сделать будет рассмотрено далее. Для того, чтобы понять как это все работает давайте рассмотрим небольшой пример.

Пример:

Для рассмотрения примера и проведения следующих экспериментов нам потребуется корабль (желательно медленный), отведите его километров на сто от станций и врат (это для того чтобы нам не мешали другие объекты) и выберите в командном меню «Нет команд». Создадим скрипт:

001 [THIS] -> set command: COMMAND_PATROL | \\команда для объекта на котором выполняется скрипт , показать текст связанный с командой COMMAND_PATROL
002 @ = wait 10000 ms | \\ так как установка команды set command действует до окончания скрипта в котором она запущена или до другой команды изменяющей установку команды, делаем задержку 10 секунд чтобы успеть посмотреть информационный экран.
003 [THIS] -> set command: COMMAND_MOVE_SECTOR | \\в этой строке меняем команду для объекта на COMMAND_MOVE_SECTOR
004 @ = wait 10000 ms | \\ еще одна задержке
005 return null | \\выход из скрипта

Этот скрипт после запуска, на десять секунд выводит в информационных экранах напротив пункта «Команда» текст «Патрулировать сектор»,

после меняет текст на «Лететь в сектор...» еще на 10 секунд,

после выхода из скрипта установиться «Нет команд».

Вы обратили внимание на то, что корабль выполняя наш скрипт не двинулся с места, несмотря на то что на информационном экране менялись команды корабля. Это наглядно демонстрирует работу команды set command и проведенный эксперимент доказывает, что данная команда имеет чисто информативное действие. И использовать ее следует для отображения текущих действий выполняемых вашим скриптом.

Еще следует заметить, что если вы установили информативной командой какое либо значение в скрипте и вызвали из него другой скрипт, в котором также производились установки информативных значений, то по возврату значение которое было до вызова скрипта восстановлено не будет, активным останется значение назначенное последней командой set command.

Далее я объясню как можно использовать свободные для использования команды и изменять связанный с ними текст. Для этого мы используем пример из раздела «Языковые файлы XML в Х2» глава «Использование пользовательских языковых файлов при работе с командным меню» воспользуемся созданным там языковым файлом:

  <?xml version="1.0" encoding="UTF-8" ?>

- <language id="7">

- <page id="2010" title="Script Cmd Names" descr="">

  <t id="715">Запуск моего скрипта</t>

  </page>

- <page id="2011" title="Script Cmd Shorts" descr="">

  <t id="715">ТЕСТ</t>

  </page>

  </language>

Этот файл при загрузке (использование в скрипте команды load text: id <языковой файл>), изменит тексты связанные с командой COMMAND_TYPE_CUSTOM_15 на странице 2010 (который также будет отражаться в виде имени пункта в меню, если использовать эту команду при его создании), а на страницу 2011 будет добавлено краткое имя команды. В нашем случае имя этого файла 70005.XML. Теперь посмотрим, что у нас получиться. Для демонстрации напишем небольшой скрипт:

001   load text id= 5

002   [THIS] -> set command: COMMAND_TYPE_CUSTOM_15

003 @ = wait 10000 ms

004   return null

Теперь вместо надписи “unknown Command!” на информационном экране в пункте команда будет отражен текст связанный с командой COMMAND_TYPE_CUSTOM_15 со страницы 2010 основного языкового файла «Запуск моего скрипта».

Еще несколько команд из группы «Общие информативные кманды»

set destination - при помощи этой команды устанавливается информационный пункт назначения для объекта выполняющего скрипт. Пунктом назначения может являться любой объект доступный для навигации (сектор, станция, корабль и т.д.).

set target, set target2 – две команды устанавливающие информативные цели. Рассмотрим на примере COMMAND_GET_WARE для этой команды <target> это товар который покупать, <target2> это станция на которой покупать. Например, создадим небольшой скрипт:

001 [THIS] -> set command: COMMAND_GET_WARE

002 [THIS] -> set target: Батареи

003 [THIS] -> set target2: Штаб-квартира ТерраКорп [Home of Light]

004 @ wait 10000 ms

005 return null

В итоге получаем две дополнительные строки в пункте «Команда»:

Дополнительно в редакторе предусмотрена комплексная информационная команда:

<object> set command: <Object Command> target=<target1> target2=<target2> par1=<Value> par2=<Value>

Эта команда объединяет в себе весь комплекс информационных команд и позволяет установить все необходимые информационные данные при помощи одной строки. А дополнительные параметры par1 и par2 позволяют ввести еще два дополнительных параметра (если они требуются).

Условные информативные команды.

К этому типу команд относятся команды которые будут выводить свои значения на информационном экране при условии что в данный момент выполняется какая либо связанная с ними команда. Отражается он в информационном пункте «Действие». Например, навигационная команда escort ship во время выполнения отразит в пункте действие «Эскорт…<объект>. В примере наш корабль эскортирует корабль «GENRY MORGAN –TS-»

Каждая навигационная команда из подобных escort ship, fly to station, fly to sector и т.д. имеет связанный с ней текст. Текст связанный с этими командами расположен на 14 странице основного языкового файла и ScE обрабатывает их на низком уровне, внести изменения в отражаемые значения при помощи скриптов не получится. Но можно изменить сам текст, изменив его в языковом файле.

Еще к условным командам можно отнести две команды из группы торговых команд set wanted ware count to и set wanted ware to эти команды предназначены для отображения дополнительной информации в меню собственности при работе команд COMMAND_GET_WARE, COMMAND_SELL_WARE или COMMAND_GET_WARE_BEST, COMMAND_SELL_WARE_BEST . Команда set wanted ware to устанавливает какой товар покупает или продает корабль, а команда set wanted ware count to устанавливает информационное значение о количестве приобретаемого или продаваемого товара, в момент загрузки этого товара на борт корабля.

Данные команды поместили свое значение в нижней строке сразу за пунктом «назначение». Команда set wanted ware to поместила значение «Кристаллы», а команда set wanted ware count to значение 24, количество купленных (загруженного на борт) кристаллов.

Команда set attack target устанавливает информационную цель атакуемую текущим объектом. На данную команду накладывается ограничение условных команд, т.е. для активации надписи должна выполняться команда атаки attack run on target активирующая пункт «атаковать» на информационном экране.

Для разбора попробуйте разобрать использование информационных команд в стандартных скриптах таких как !ship.cmd.getware.std, !ship.cmd.sellware.std, !ship.cmd.attack.std и подобных скриптах.


Языковые файлы XML

Языковые файлы XML в Х2

v Что такое языковой файл

Вся текстовая информация использующаяся в Х2 (описания товаров, название команд меню, фразы в приходящих игроку сообщениях и т.п.) хранится во внешних XML файлах. Данные файлы содержат в себе полностью всю текстовку, что очень облегчает перевод Х2 на другие языки. Основным языковым файлом является файл ХХ0001.XML, где ХХ это цифровой идентификатор языка под который локализована информация содержащаяся в файле. Именно в этом файле хранится весь текст относящийся к игре. Также в комплекте с игрой идет файл ХХ0002.XML, он содержит тексты для первого диалогового окна, появляющегося перед запуском игры (настройка графики, логотип, управление и т.п). Ниже приведены ХХ коды и языки соответствующие им ( на самом деле коды соответствуют телефонным кодам стран, где данный язык является основным):

ХХ код | Язык локализации
7 | Русский
33 | Французский
39 | Итальянский
44 | Английский
48 | Польский
49 | Немецкий

Эти файлы находятся в папке /t каталога в который установлена игра. Это верно для распакованной версии игры (изначально игра находится в упакованном виде).

Второй вариант расположения файлов это подобные zip архивам, файлы *.CAT - файлы каталогов, *.DAT - файлы данных. В веси 1.4 имеется четыре пары файлов от 01.CAT/01.DAT и соответственно до 04.CAT/04.DAT. Х2 имеет доступ к упакованным файлам, также как, если бы он находились в распакованном состоянии и были разложены по обычным папкам. Чтобы нам получить доступ к этим файлам, необходимо распаковать эти файлы. Делается это при помощи официальной программки «X2 modder kit» или «X2 modder» от OlisJ. Для русскоязычных пользователей гораздо удобней воспользоваться утилитой написанной пилотом Dimaxx’ом, называется она XTdat.exe. Программа имеет русскоязычный интерфейс и легка в использовании. Найти эту программку можно здесь: http://www.elite-games.ru/_egm_scripts/url.php?action=gotourl&url=/downloads/x2/xtdat.exe.

После распаковки, файлы содержащиеся в CAT/DAT файлах будут извлечены и разложены по соответствующим папкам. Открываем папку /t в игровой директории в ней должны появиться файлы 440001.XML и 440002.XML для англоязычной версии или 70001.XML и 70002.XML для русскоязычной (дальше, везде будет рассматриваться русская версия Х2). Если ваша игра локализована под другой язык, то идентификатор языка будет соответствовать языку локализации (см.табл).

v Как делается языковой файл и при помощи какой программы

Поняв основное назначение языкового файла и прежде чем перейти к более глубокому рассмотрению данного вопроса. Следует разобраться при помощи какой программы можно посмотреть содержимое языкового файла, редактировать и создавать новые. Ответ прост. Самой удобной программой для работы с языковыми файлами является стандартный виндосовский блокнот, а программой для просмотра содержимого Internet Explorer. Любой языковой файл легче всего не создавать с нуля а взять какой ни будь готовый и подредактировать его. Если у вас нет под рукой ни одного маленького языкового файла, то воспользуемся поставляемым с игрой файлом 70002.XML. Открываем папку /t из игровой директории и открываем файл 70002.XML при помощи блокнота. Удаляем текст от строки <page id="1912" title="Graphic Settings dialog" descr=""> до самого конца оставив только последнею строчку </language>. В разделе <page id="1910" title="About Dialogue" descr="First dialogue before start of game - About"> удаляем все между <t id="1">Запустить X2</t> и </page>

У нас должен получиться файл следующего содержания:

<?xml version="1.0" encoding="UTF-8" ?>

<language id="7">

<page id="1910" title="About Dialogue" descr="First dialogue before start of game - About">

<t id="1">Запустить X2</t>

</page>

</language>

Удаляем 1910 в page id, «About Dialogue» в title и «First dialogue before start of game – About» в descry. Строчкой ниже удаляем 1 из “t id=” и «Запустить X2»

Получаем:

<?xml version="1.0" encoding="UTF-8" ?>

<language id="7">

<page id=" " title=" " descr=" ">

<t id=" "> </t>

</page>

</language>

Выбираем «сохранить как», исправляем имя на 70005.XML (расширение указывать обязательно), устанавливаем кодировку UTF-8, сохраняем. Теперь у нас есть файл шаблон языкового файла с именем 70005.XML.

v Использование пользовательских языковых файлов при работе с командным меню

Теперь мы знаем, что обозначает первая часть имени языкового файла. Давайте теперь разберемся, что означают четыре оставшиеся цифры в имени. Эти цифры, называются персональным идентификатором языкового файла. Этот идентификатор (ID) нужен для того, чтобы любой скрипт мог получить доступ к содержимому любого языкового файла. Осуществляется этот доступ по средствам инструкции load text, инструкция использует ID для того, чтобы определить к какому из имеющихся языковых файлов хочет получить доступ текущий скрипт. Х2 позволяет пользователю использовать до 9997, произвольных языковых файлов (например имена файлов: 70003.XML, 70004.XML, 70010.XML и т.д., кроме зарезервированных системных файлов 70001.XML и 70002.XML).

Пользовательские языковые файлы могут быть использованы для загрузки в Х2 описаний новых товаров, команд в меню, размещения шаблонов текстов и т.п., используемых игроком в своих скриптах. Для того чтобы было понятно рассмотрим небольшой файл пример:

  <?xml version="1.0" encoding="UTF-8" ?>

- <language id="7">

- <page id="2008" title="Script Object Commands" descr=" ">

  <t id="715">Команда_мой_скрипт</t>

  </page>

- <page id="2010" title="Script Cmd Names" descr=" ">

  <t id="715">Запуск моего скрипта</t>

  </page>

- <page id="2011" title="Script Cmd Shorts" descr=" ">

  <t id="715">Тест</t>

  </page>

- <page id="2022" title="Command Info" descr=" ">

  <t id="715">Изучение процесса создания дополнительных команд.</t>

  </page>

  </language>

Как видите язык файла указан не только в имени файла, но и в теле самого файла.

Любой языковой файл (в том числе и 70001.XML) разделен на страницы (page id= ), и на текстовые идентификаторы внутри страницы (t id= ), то есть принцип папок и подпапок в обыкновенной файловой системе.

Прежде чем двигаться дальше, объясню как будут располагаться в памяти языковые файлы. Основным файлом описания является файл 70001.XML, он загружается в память при загрузке игры. Все языковые файлы создаваемые и используемые вами, загружаемые в память при помощи инструкции load text, будут дополнять или изменять, уже загруженный в пямять основной языковой файл 70001.XML, а ScE будет обращаться непосредственно к нему. Имейте в виду, что если два пользовательских языковых файла обратятся к одному и тому же текстовому ID на одной странице и изменят его значение, то актуальным будет то значение которое было записано последним.

В основном файле имеется четыре страницы которые вы будите использовать в своих скриптах при организации работы командного меню корабля:

2008 | Эта страница содержит все мнемонические имена команд/сигналов. Мнемонические имена используются инструкциям для которых команды/сигналы являются параметрами. Примером таких инструкций служат global script map и set script command upgrade. Если вы используете в вашем скрипте какую нибудь из этих инструкций то при выборе команды/сигнала редактор отразит весь список мнемонических имен команд содержащихся на странице 2008 основного языкового файла.
2010 | Эта страница содержит текст являющийся длинной версией имени команды. То есть этот текст отражаемся в виде пункта в меню. Также именно этот текст будет отражен в разделе команда информационного экрана и в разделе команда списка вашей собственности (при условии что в теле вызываемого будет присутствовать инструкция set command, иначе во всех информационных окнах вместо имя выполняемой команды будет отражаться «Нет команд»)
2011 | На этой странице находятся короткие имена команд. Короткие имена отражаются в командном меню справа от длинных имен, тек же короткое имя команды отражается в верхней части экрана также справа от длинного имени в главном окне командного меню .
2022 | На этой странице находится краткое описание вашей команды. Это описание не является обязательным, но не забывайте что ваши скрипты будут использовать другие пилоты, и по этому желательно создавая в командном меню новую команду, делать для нее краткое описание. Наличие данного описания на соответствующей странице добавит небольшой значок в виде буквы «i», между длинным и коротким именем команды при отражении меню, а при нажатии на клавишу «i», при курсоре установленном на вашу команду на экране отразиться окно содержащее описание вашей команды.

В нашем примере на странице 2008 мы заменяем мнемоническое имя команды COMMAND_TYPE_CUSTOM_15 находящиеся за текстовым идентификатором 715 на имя заданное нами Команда_мой_скрипт (обратите внимание на то, что после изменения мнемонического имени команды, при попытке выбрать ее через меню редактора, вы можете не обнаружить ее на старом месте. То есть между COMMAND_TYPE_CUSTOM_14 и COMMAND_TYPE_CUSTOM_16, причина тому, фильтр редактора который сортирует список по латинскому алфавиту). Далее на странице 2010 по ID=715 записываем «Запуск моего скрипта», а на странице 2011 в ID с тем же номером записываем короткое имя нашей команды «Тест». И не забываем создать краткое описание нашей команды, разместив на странице 2022 в идентификаторе 715 текст описания «Изучение процесса создания дополнительных команд.»

Языковой файл для команды COMMAND_TYPE_CUSTOM_15 создан. Теперь когда мы произведем инициализацию нашей команды (как это сделать рассмотрим дальше), в командном меню в разделе Выборочные команды будет отражен пункт меню с названием «Запуск моего скрипта», а чуть правее в квадратных скобках будет указано краткое имя команды [Тест]. Между именами отразиться значок «i», сообщающий о наличии описания для команды вызываемого нажатием клавиши «i».

Далее в таблице будут приведены команды, их тип и ID, меню в которых они располагаются.

Тип | ID | Меню | Мнемоническое имя
Navigation | 200-23 1 | Командное меню, Навигация | COMMAND_TYPE_NAV_00 to 31
Combat | 300-33 1 | Командное меню, Боевые | COMMAND_TYPE_FIGHT_00 to 31
Trade | 400-43 1 | Командное меню, Торговые | COMMAND_TYPE_TRADE_00 to 31
Special | 500-53 1 | Командное меню, Специальные | COMMAND_TYPE_SPECIAL_00 to 31
Piracy | 600-63 1 | Командное меню, Пиратские | COMMAND_TYPE_PIRACY_00 to 31
Custom | 700-73 1 | Командное меню, Выборочные | COMMAND_TYPE_CUSTOM_00 to 31
General | 800-83 1 | Командное меню, Общие | COMMAND_TYPE_GENERAL_00 to 31
Turret | 900-93 1 | Меню турелей (из основного меню) | COMMAND_TYPE_TURRET_00 to 31
Station | 1100-113 1 | Командная консоль станций | COMMAND_TYPE_STATION_00 to 31
Ship | 1200-123 1 | Дополнительные корабельные команды | COMMAND_TYPE_SHIP_00 to 31

В данной таблице указанны все возможные пункты меню. При выборе на какой пункт меню «зацепить» вашу команду имейте в виду следующее: в каждом пункте меню первые шестнадцать команд зарезервированы Egosoft, для подписанных ими Plugin. И вообще если вы используете в игре несколько скриптов написанных разными авторами, то не поленитесь заглянуть в инициализирующие файлы и посмотреть какие команды используют эти скрипты. Если вы увидите, что два каких то скрипта ссылаются на одну и туже команду вам придется немного изменить один из скриптов, назначив ему другую команду. Если этого не сделать, то скрипт который загрузится последним перехватит все управление на себя.

v Инициализация языкового файла

Для того, чтобы языковой файл загрузился и произвел соответствующие изменения в загруженном основном языковом файле. Необходимо создать небольшой скрипт инициализации назовем его init.a вот его исходный текст:

Script init.a

Version: 0
for Script Engine Version: 25

Description

Описание

Arguments

Source Text

 001   load text: id=5
 002   $command = Команда_мой_скрипт
 003   global script map: set: key=$command, class=Корабль, race=Player, script='a.missile.fire',prio=0
 004   global script map: ignore: key=$command, class=Дрон, race=Player
 005   set script command upgrade: command=Команда_мой_скрипт  upgrade=[TRUE]
 006   return null

В строке 001 загружаем языковой файл 70005.XML, 003 устанавливаем связь между командой и скриптом a.missile.fire, для подключения в меню Выборочных команд у объектов класса Корабль пункта который будет вызывать наш скрипт. 004 Исключаем из списка объектов, класс объектов Дрон. Устанавливаем наличие апгрейда необходимого для активации пункта в меню, в нашем случае значение [TRUE], то есть пункт будет активен всегда. Если все готово производим реинициализацию скриптового КЭШа как это было описано в разделе «Редактор скриптов». Если все правильно то в меню должен появиться Выборочных команд появится команда « Запуск моего скрипта»

v Пользовательские языковые файлы для создания текстовых шаблонов

Если вы взялись за создание какого либо скрипта, то вполне возможно, что вам понадобится вывести какие либо текстовые данные (яркий пример, это любой текст на русском языке. Х2 не позволяет вводить русские символы в редакторе скриптов). Для того чтобы использовать текстовые шаблоны или просто обойти запрет на введение русских символов можно также использовать языковые файлы. Давайте попробуем записать какой ни будь русскоязычный текст в бортовой журнал нашего корабля.

Для начала определим на какой странице, и какой “t id” нам надо использовать для хранения шаблона нашего текста. Принцип выбора прост. Шаблон можно хранить на любой доступной странице, следует лишь использовать уникальный “t id” , то есть открываем в IE файл 70001.XML и смотрим. На странице 1 (<page id="1" title="Root page" descr="">) имеется пять элементов с “t id” 1,2,3,5, 9999999 соответственно все “t id” между 5 и 9999999 свободны.

Воспользуемся этим. Открываем наш файл шаблон в блокноте и заполняем данными page id="1", " title="Root page” должно получиться следующее:

<?xml version="1.0" encoding="UTF-8" ?>

<language id="7">

<page id="1" title="Root page" descr=" ">

<t id="100"> Это мой русскоязычный текст</t>

</page>

</language>

Сохраняем его, запускаем игру, заходим а редактор скриптов и делаем небольшой скриптик:

Script Print.main.rustext

Version: 0
for Script Engine Version: 25

Description

Print to logbook russian text

Arguments

Source Text

 001   load text: id=6
 002   write to player logbook: printf: pageid=1 textid=100, null, null, null, null, null
 003   return null

Запускаем созданный нами скрипт. Выходим из редактора и открываем бортовой журнал если вы правильно выполнили все действия, то в журнале будет новая запись с текстом «Это мой русскоязычный текст»

v Использование тэгов и спец. символов для оформления текстов.

Играя в Х2, вы наверное обратили внимание на то как оформлен текст в досках объявлений на станциях, а также над тем, что многие сообщения записанные в вашем бортовом журнале содержат цветные вставки, текст располагается в несколько колонок или центрирован по середине и т.п. О том как это делается мы рассмотрим в этой главе.

В Х2 имеется возможность форматирования текстов реализована по средствам использования тэгов и спец.символов. Тэги предназначены для форматирования, изменения цвета текста используемого в сообщениях Х2 и заключенного между ними. Спец символы используются для изменения цвета текста следующего за ними, ввода в тело текста вычисляемого значения или параметра. Х2 использует два типа спецсимволов. Первый тип форматирующие спецсимволы, к ним относятся спецсимволы изменяющие цвет текста и строчные спецсимволы такие как перевод строки табуляция. Второй тип, это спецсимволы значений, используются для размещения в теле текста вычисляемых значений.

Форматирующие спецсимволы.

Сначала давайте рассмотрим спецсимволы, которые используются для изменения цвета текста сообщений, а также выполнения некоторых строчных действий. Любой форматирующий спецсимвол в Х2 начинается со знака « \ », и доступен для использования только при помощи текстовых шаблонов из языковых файлов. Формат записи форматирующих спецсимволов изменяющих цвет следующий: \033<символ цвета>. Обратите внимание на то, что цветовые спецсимволы делают установку для всего идущего за ним тексом, то есть цвет текста не изменится до следующего встреченного в тексте цветового спецсимвола или тэга. Т.е если вы например, сделали цветным имя какого-либо объекта и не восстановили цвет использую спецсимвол закрытия цвета (возвращение к стандартному цвету), то в игре, если вы захотите добавить что ни будь к имени, то добавленный текст также отразиться цветом установленным спецсимволом в начале имени. Если же в стоке будет стоять тэг, то после его обработки установка цвета будет изменена на стандартный. Также к стандартному цвету возвращает спецсимвол перевода строки \n. Обязательно учитывайте эти факты работая над своими текстами к своим скриптам. И если вы использовании спецсимвол цвета не забывайте закрывать его возвращением к стандарту.

Спецсимвол | Цвет
Цветовые
\033B | Синий
\033C | Голубой
\033G | Зеленый
\033M | Малиновый
\033R | Красный
\033W | Белый
\033X | Ярко-белый (стандарт для меню)
\033Y | Желтый
\033Z | Серый (стандарт для сообщений)
Форматирующий
\n | Перевод строки

Пример:

создадим файл 70007.XML

<?xml version="1.0" encoding="UTF-8" ?>

<language id="7">

<page id="1" title="Root page" descr=" ">

<t id="100">\033B Синий\n\033G Зеленый\n\033R Красный</t>

</page>

</language>

и скрипт для запуска с именем Print.sym:

Script Print.sym

Version: 0
for Script Engine Version: 25

Description

Описание

Arguments

Source Text

 001   load text: id=7
 002   $str = sprintf: pageid=1 textid=100, null, null, null, null, null
 003   write to player logbook $str
 004   send incoming message $str to player: display it=[TRUE]
 005   return null

запустим его. Получаем сообщение следующего вида:

Как мы видим текст отражен цветами согласно указанным нами спецсимволов, а спецсимвол «\n» обеспечил перевод строки. Из форматирующих спецсимволов, я нашел только два это использованный нами «\n» и еще есть «\t» - табуляция, но к сожалению не доступен ScE, использует его только сам движок игры при построении различных help-экранов. Например: вкладка «?» в картах галактики и сектора.

Спецсимволы вычисляемых значений

Очень часто при написании скрипта, требуется послать сообщение в котором в текстовом сопровождении указывалось бы несколько значений, не имеющих постоянной величины. Например сообщить игроку что в каком то секторе, на какой то принадлежащий вам транспортный корабль было совершено нападение, каким то кораблем, принадлежащим какой то расе. То есть, предположим у нас есть скрипт который следит за подобными ситуациями и отправляет вам отчет такого рода.

Прежде чем рассматривать дальше наш пример, сделаю небольшое отступление. Спецсимволы вычисляемых значений (далее в тексте СВЗ) , в отличии от спецсимволов форматирования доступны для использования как из языковых файлов так и непосредственно из редактора при вводе текстового значения переменной. Для работы со строками содержащими СВЗ в редакторе используются следующие команды:

из раздела общие команды

<RetVar>=sprintf: fmt=<Var/String>, <Value1>, <Value2>, <Value3>, <Value4>, <Value5>

<RetVar>=sprintf: pageid=<Var/Number1> id=<Var/Number2>, <Value1>, <Value2>, <Value3>, <Value4>, <Value5>

Первая команда записывает в переменную <RetVar> текстовую строку составленную из строки формата <Var/String> в которой все СВЗ заменены значениями Value. В одной строке формата может присутствовать до пяти вычисляемых значений. Вторая команда выполняет те же действия, с той разницей, что строка формата берется из языкового файла (почти все скрипты отдают предпочтение второй команде, т.к. использование языковых файлов позволяет использовать тексты на любом языке, в то время как редактор, использует только латинскую раскладку)

из раздела «Работа с бортовым журналом» используются очень похожие команды:

write to player logbook: printf: fmt=< Var/String >, < Value1>, <Value2>, < Value3>, < Value4>, < Value5>

write to player logbook: printf: pageid=< Var/Number1>, textid=<Var/Number2>, < Value1>, < Value2>, < Value3>, < Value4>, < Value5>

Различия этих команд заключаются в том, что две последних команды выводят строку непосредственно в бортовой журнал.

Теперь давайте рассмотрим какие спецсимволы вычисляемых значений мы можем поместить в строку формата. Все СВЗ начинаются с символа «%» далее сам символ интерпретируемый ScE . В таблице указаны все СВЗ и их описание:

Спецсимвол | Описание
%s | Вставить значение Value1-5 в зависимости от того каким по счету стоит этот символ. То есть, если в строке присутствует несколько символов %s, то на место первого будет вставлено значение Value1, на место второго Value2 и т.д.
%d | (Decimal) вставить десятичное значение, в отличии от %s строкового. То есть при попытке напечатать 0 - получается "пусто" или "null".
%!<n>s | Вставить значение не в общем порядке, а указанное в <n>. Например: Если в n указано 3, то будет вставлено значение Value3.
%<n>s | В этом месте строка раздвигается на количество символов указанное в <n>, на освободившиеся место записывается столько символов параметра, сколько поместится. Если параметр короче чем строка формируемая параметром, то выравнивание будет производится по правому краю отведенного места.
% - <n>s | Действует также, как и спецсимвол %<n>s, с тем отличием, что выравнивание будет производится по левому краю отведенного места.
*Использование угловых скобок условно.

Теперь мы рассмотрев возможные СВЗ, давайте вернемся к нашему примеру и попытаемся создать оговоренное выше сообщение. И так, предположим, что некий глобальный скрипт отследил ситуацию о нападении на ваш транспортный корабль и поместил в переменные интересующие нас данные. Переменная $sector=<сектор в котором произошло нападение>, $MainShip=<атакуемый корабль>, $EnemyShip=<корабль агрессора>, $EnemyRace=<раса агрессора>. Строка помещающая сообщение об атаке в бортовой журнал, будет выглядеть так:

…

057 write to player logbook: printf: fmt=’Ваш корабль %s находясь в секторе %s, был атакован кораблем %s принадлежащим расе %s’, $MainShip, $sector, $EnemyShip, $EnemyRace, null

…

* русские символы условны, для использования русской раскладки необходимо использовать языковой файл и команду write to player logbook: printf: pageid= textid=.

Посланное нам сообщение будет выглядеть, приблизительно, вот так:

Теги форматирования.

Теги представляют их себя двух компонентный спецсимвол состоящий из открывающего тэг-символа “[b]” и закрывающего “[/b]” (в примере тэг устанавливающий желтый цвет для текста заключенного нем). Все тэги оказывают свое действие, только на текст размещенный между открывающим и закрывающим тэг-символом. Есть еще одна приятная особенность в использовании тэгов – это, поддержка вложенности, то есть в тело одного тэга может быть вложен другой.

Присутствующие в Х2 тэги, делятся на две группы: простые и специальные:

Простые теги.

К простым тэгам относятся теги, выполняющие операции над форматом и цветом.

Формат тега | Описание
[b] text [/b] | Текст отражается ярко-желтым цветом
[blue] text [/blue] | То же голубым цветом
[red] text [/red] | То же красным цветом
[green] text [/green] | То же зеленым цветом
[justify] text [/justify] | Текст выравнивается по краям
[center] text [/center] | Текст центрируется
[left] text [/left] | Текст выравнивается по левому краю
[right] text [/right] | Текст выравнивается по правому краю
[title] text [/title] | Текст отражается в виде заголовка по центру, подчеркнутый, весь остальной текст будет иметь отступ от него одну пустую стоку.

С использованием простых тегов, не должно возникнуть ни каких проблем. Переходим к рассмотрению более сложных специальных тэгов.

Специальные теги

К специальным тэгам относятся теги выполняющие более сложные действия форматирования требующие введения дополнительных числовых значений, либо осуществляющие двустороннею связь (то есть ожидающие реакции пользователя).

Формат тега | Описание
[author]автор[author] | в сообщении в поле "от кого" будет указана строка "автор". Этот тэг должен быть самым первым в теле сообщения
[text cols='число колонок' colwidth='ширина колонки' colspacing='расстояние между колонками']текст[/text] | если этот тэг присутствует, он должен идти сразу за тэгом [author] (если тэг [author] также присутствует) или в самом начале тела сообщения. Закрывающий тэг [/text] безусловно обрывает текст сообщения. Параметры cols, colwidth и colspacing могут присутствовать или отсутствовать независимо друг от друга. В чем задается ширина колонки и расстояние между колонками - неясно. В режиме экрана 640x480 эти числа, похоже, совпадают с пикселями экрана. Для других режимов пропорции нужно высчитывать.
[select] text [/select] [select value='Start'] text [/select] | Текст заключенный в тэге [select] выведенный командой send incoming message отображается в виде выбираемого пункта, но похоже что в ScE не предусмотрена возможность возврата значения этим тэгом, и его использует сам движок игры. Но все равно ему можно найти применение, так как, если отображать текст из этого тэга в бортовом журнале, то текст будет выделен (отображен на сером фоне). Но тег будет действовать только до перевода строки.

Для наглядного разбора возьмите сообщение о миссии из станционных BBS, например, о спасении дочери королевы Артеи находится он на странице 1292, page ID=1, языкового файла 70001.XML. Пошлите его при помощи его при помощи вот этого скрипта и разберитесь что и как в этом сообщении организовано.

Script a

Version: 0
for Script Engine Version: 25

Description

Описание

Arguments

Source Text

 001   $str = sprintf: pageid=1 textid=100, null, null, null, null, null
 002   send incoming message $str to player: display it=[TRUE]
 003   return null

Не обращайте внимания на то, что вместо некоторых данных отражается null, это связано с тем что мы искусственно вызвали этот текст и движок игры не обрабатывает его.

Вот текст содержащийся на указанной странице:

[title]СРОЧНО! ПОМОГИТЕ СПАСТИ МЕНЕЛАЮ![/title][text cols='2' colwidth='250' colspacing='50'][justify] Внимание! Срочное сообщение! Нам, боронам, нужна помощь. [b]Менелая[/b], дочь Королевы Атреи, заразилась вирусом Борусдектус. Если ей не будет оказана помощь в течение [green]%s[/green], она умрет. К сожалению, необходимые медикаменты очень трудно достать легальным путём. Можно конечно их и синтезировать, но нам нужно для этого как минимум %s! Если хотите помочь нам найти эти компоненты, вы должны привезти их в течение [green]%s[/green] на [b]королевскую торговую станцию[/b] в секторе [blue]Kingdom End[/blue].[/justify]\n\n[center][select value='Start']Да, я согласен![/select]\n\n[select value='MoreInfo']Дополнительная информация[/select][/center][/text]

Думаю у вас не должно возникнуть проблем, с пониманием использования тэгов в этом сообщении.

Спецтег ссылка

Существует еще один специальный тег позволяющий избежать многократных повторений некоторых одинаковых фрагментов фраз, сообщений и т.п. Данный тег позволяет использовать в текущем фрагменте фрагмент находящийся в основном языковом файле на другой странице, то есть произвести вставку внутрь текста. Ссылка на требуемую страницу размещается внутри фигурных скобок, в которые через запятую записываются два числовых значения, первое – это страница, второе – это идентификатор. ScE встретив в тексте этот тег, заместит его текстом из соответствующего идентификатора. Например:

 < t id="1321">Вооружение</t>

< t id="1322">Корпус корабля</t>

< t id="1323">повреждён</t>

< t id="1324">{13,1322} {13,1323}</t>

В данном примере взятом из стандартного языкового файла 70001.xml со страницы 13 (Фразы бортового компьютера), видно что идентификатор 1324 содержит не текст, а ссылки на два предыдущих идентификатора с этой же страницы и соответственно обратившись к этому идентификатору мы получим фразу «Корпус корабля поврежден», составленную из текста находящегося в ID 1322 «Корпус корабля» и ID 1323 «поврежден».


Особенности некоторых команд

v Особенности навигационных команд (FLY). Возвращаемый код FLRET

Прежде всего о навигационных командах семейства Fly to…, Move to…, Follow to… нужно сказать, что все семейство относится к разряду прерываемых команд, то есть все они помечены значком «@». Это означает, что выполнение данной команды может быть прервано скриптом или сигналом имеющим более высокий приоритет. Еще одна особенность этих команд, это нелимитированость времени выполнения (исключение команды имеющие параметр timeout), то есть пока корабль не прилетит в указанное место, скрипт запустивший эту команду, будет ожидать ее завершения.

Все навигационные команды из этого семейства, возвращают значение содержащее информацию о результате выполнения команды. Для этих целей используется специально зарезервированный в ScE список кодов возврата, доступных для выбора из списка «Выберете код возврата» в скриптовом редакторе. Это коды FLRET_<значение>. Эти коды могут являться аргументами для оператора “IF” “IF NOT” “SKIP” “SKIP NOT” и т.п.

Также вам следует знать, что не каждой команде из этого семейства доступен весь список кодов FLRET, для некоторых из них доступны лишь несколько значений. Далее, в описании команд, для команд из этого семейства будут указываться доступные константы.

Здесь приведен полный список кодов FLRET:

Константа FLRET | Описание
FLRET_INVALIDPARMS | – Указан неверный параметр команды
FLRET_DESTROYED | – Объект команды уничтожен
FLRET_LANDED | – Объект команды пристыкован/пристыковался
FLRET_WARPED | – Объект команды совершил прыжок через врата
FLRET_NOCOMMANDS | – Аргумент команды не существует
FLRET_IMMEDIATE |
FLRET_ERROR | – Во время выполнения команды произошла ошибка
FLRET_INTERRUPTED | – Выполнение команды было прервано другим скриптом
FLRET_BREAK | – Команда по какой-либо причине не может быть выполнена
FLRET_FIREFREE | – Цель в радиусе поражения, можно стрелять
FLRET_TARGETREACHED | – Цель достигнута
FLRET_NEXTFLIGHTSTEP | – Часть команды выполнена, исполняется следующая часть
FLRET_TIMEOUT | – Время, отведенное на выполнение команды истекло

v Организация глобального поиска объектов. Флаги поиска (Find).

Под глобальным поиском подразумевается, сложный поиск определенного объекта в пределах игровой галактики или сектора. Для этого служат команды из семейства FIND, относящихся к группе «Работа с объектами». Аргументы команд выполняющих поиск в секторах немного отличаются от аргументов команд ищущих по всей галактике. В этой главе, будут описаны основные параметры команд поиска. Поиск строится с использованием специальных флагов (Find. <значение>) и большого набора параметров. Рассмотрим на примере команды find station выполняющей поиск станции внутри сектора:

<RetVar/IF> find station: sector=<Var/Sector> class or type=<Value1> race=<Var/Race> flags=<Var/Number1> refobj=<Value2> maxdist=<Var/Number2> maxnum=<Var/Number3> refpos=<Var/Array>

sector – необходимо указать сектор поиска, если этот параметр не указан, то поиск не будет произведен и функция вернет null. В командах галактического поиска, на месте этого параметра как правило указывается сектор, от которого следует начать искать.

class or type – Это параметр задается в том случае, если надо искать станцию определенного типа (например док) выбирать его следует из списков «Типы объектов» или «Класс объекта» предлагаемого редактором , если этот аргумент поставить null – в поиск буду включены все станции любой расы. Это аргумент связан с аргументом «race» через логического “И”

race – тоже самое, что и предыдущий параметр, только указывается раса владельца объект. Если параметр null, то раса значения иметь не будет.

flag – данный параметр является константой и определяет флаг для поиска. Флаги производят более тонкую настройку для поиска и отфильтровку требуемого объекта или объектов. Вообще параметр имеет числовой формат (Var/Number), связано это с тем, что каждая константа Find, имеет числовое значение соответствующее ей. Флаг поиска может использоваться как в одиночку, так и в виде наборов флагов дополняющих или исключающих друг друга, составленных через бинарный логический оператор добавляющего ИЛИ «|», простые логические операторы «AND» или «OR», здесь негодятся. Например: Find.Neutral|Find.Nearest – поиск ближайшей станции только среди нейтральных – аналогия логического «И». А если написать Find.Neutral|Find.Enemy – поиск среди нейтральных или враждебных – аналогия логического «ИЛИ».

Если введен особый флаг Find.Multiple, то функция ВСЕГДА возвращает массив, и далее с этим результатом можно работать только, как с массивом, даже если он состоит из 1 элемента.

Флаг поиска | Значение | Описание | Используется
Find.IllegalWare | 0х00800000 | Искать не законный товар | Find flying ware
Find.Random | 0x01000000 | Найти случайный объект | Все
Find.Nearest | 0x02000000 | Найти ближайший объект относительно «refobj» | Все
Find.ExactJumps | 0x04000000 | Искать в секторах находящихся, ровно в указанном в <maxjumps> количестве прыжков, ни больше, ни меньше. | Find station in galaxy
Find.Enemy | 0x08000000 | Объектами для выбора будут являться все объекты являющиеся врагами. Если присутствуют Find.Neutral и/или Find.Friend, они тоже попадут в поиск. | Все
Find.Neutral | 0x10000000 | Объектом поиска будут являться, все объекты не являющиеся врагами и не принадлежащие игроку. Если присутствуют Find.Enemy и/или Find.Friend, они тоже попадут в поиск. | Все
Find.Friend | 0x20000000 | Объектом поиска будут являться все дружественные объекты(как правило принадлежащие игроку). Если присутствуют Find.Enemy и/или Find. Neutral, они тоже попадут в поиск. | Все
Find.Multiple | 0x40000000 | Помещать все найденные объекты в массив. Если установлен этот флаг то дальнейшие действия с переменной <RetVar/IF> должны производится как с массивом. | Все кроме find station in galaxy
Find.ForceUsePos | 0х400000 | Начинать поиск от точки указанной в «refpos» | Find в секторе
Find.TypeAsWareCategorie | 0x80000000 | Не используется |

refobj – вообще этот параметр введен для того, что использовать его с флагом Find.Nearest оказывает он два действия:

1.данный объект исключается из поиска, если потенциально он в него может попасть.

2. служит точкой отсчета. Если, например, стоит флаг Find.Nearest, поиск ближайшей станции будет осуществляться относительно этого refobj

maximum – максимальный размер массива, работает только с флагом Find.Multiple, в противном случае результатом будет 1 станция (или null, если ничего не нашлось), а данный аргумент на поиск не влияет.

maxdist – ограничивает радиус поиска относительно точки отсчета: refobj или refpos. А если точки отсчета нет, то за точку отсчета принимается центр сектора. Если null – ограничения нет.

refpos – точка отсчета, массив из 3 координат x,y,z. Если ввести refpos и refobj одновременно, поиск будет относительно refobj. А если дополнительно установить флаг Find.ForceUsePos, то точка отсчета refpos оказывается главнее, чем точка отсчета refobj, поиск будет вестись относительно refpos.

В командах поиска по галактике, присутствуют еще несколько параметров:

max.jumps – Содержит максимальное количество прыжков до секторов в которых будет производиться поиск, от сектора где находится refobj.

serial – Для выбора по номерам станций (альфа, бета, гама).

num – Указывается сколько объектов соответствующих условиям поиска выбрать, обязательно должен быть установлен флаг Find.Multiple.


ПРАКТИКУМ

v Добавление новой команды в консоль.

Как вы уже поняли ScE Х2 позволяет пользователю добавлять новые команды в командное меню объектов. Также, существует некоторый алгоритм позволяющий сделать команду доступной лишь для определенного типа объектов и при возникновении определенных условий. Принцип добавления новой команды был рассмотрен в разделе «Языковые файлы», далее в этой главе мы детально рассмотрим весь процесс добавления команды и установке ее связи с назначенным скриптом. Всю последовательность действий можно разделить на несколько шагов:

Шаг 1. Определение пункта меню для новой команды.

Прежде всего следует определить в какой слот командного меню вы хотите добавить новую команду. ScE позволяет добавить команду в один из 10 стандартных пунктов командного меню.

Далее, в таблице будут приведены пункты командного меню и мнемонические имена команд находящихся в этих пунктах, а также соответствующие им ID на страницах основного языкового файла. Как все это использовать в ваших скриптах, мы рассмотрим далее.

Тип | ID | Меню | Мнемоническое имя
Navigation | 200-231 | Командное меню, Навигация | COMMAND_TYPE_NAV_00 to 31
Combat | 300-331 | Командное меню, Боевые | COMMAND_TYPE_FIGHT_00 to 31
Trade | 400-431 | Командное меню, Торговые | COMMAND_TYPE_TRADE_00 to 31
Special | 500-531 | Командное меню, Специальные | COMMAND_TYPE_SPECIAL_00 to 31
Piracy | 600-631 | Командное меню, Пиратские | COMMAND_TYPE_PIRACY_00 to 31
Custom | 700-731 | Командное меню, Выборочные | COMMAND_TYPE_CUSTOM_00 to 31
General | 800-831 | Командное меню, Общие | COMMAND_TYPE_GENERAL_00 to 31
Turret | 900-931 | Меню турелей (из основного меню) | COMMAND_TYPE_TURRET_00 to 31
Station | 1100-1131 | Командная консоль станций | COMMAND_TYPE_STATION_00 to 31
Ship | 1200-1231 | Дополнительные корабельные команды | COMMAND_TYPE_SHIP_00 to 31

Для того, чтобы продолжить изучение, давайте установим задачу и на ее примере рассмотрим все действия. Задача: Добавить в командное меню команду запускающую некий патрульный скрипт patrol.script.xml, на кораблях класса М6, М2 исключая запуск на кораблях других классов. Данная команда должна быть доступна только кораблям имеющим Боевой софт МК1.

Теперь приступим к определению пункта командного меню в котором следует расположить создаваемую нами команду. Так как, наш скрипт управляет боевым кораблем и выполняет военные действия, т.е. «патрулирование», то логично было бы расположить новую команду в пункте «Боевые». Определившись с тем, в какой пункт мы будем размещать новую команду, переходим к выбору самой команды.

Для каждого слота в ScE предусмотрено 32 команды. Обратите внимание на то что некоторые из них могут быть уже использованы самим Егософтом или другими скриптами. Мы остановимся на команде COMMAND_TYPE_FIGHT_15. То есть, выбор слота в командном меню мы осуществляем из принципа логичности, а команду выбираем из тех, что не заняты.

Шаг 2. Определение имени команды.

Следующим шагом является определение имени команды, т.е. загрузка текста который будет отражаться в строке меню данной команды. Если этот шаг будет пропущен, то новая команда в меню, отразится как ReadText2010-315 и ReadText2011-315, выглядеть наглядно это будет приблизительно так:

Для того чтобы отразить имя команды в том виде, что нам нужно: мы должны создать языковой файл и ввести соответствующие значения на страницы и в идентификаторы соответствующие новой команде. В нашем случае это страницы 2010 и 2011, а идентификатор ID 315 соответствующий команде COMMAND_TYPE_FIGHT_15 . И не забывайте про краткое описание вашей команды вызываемое клавишей «i». Как произвести эти операции подробно описано в разделе «Языковые файлы XML в Х2» глава «Использование пользовательских языковых файлов при работе с командным меню».

Вот необходимый нам языковой файл назовем его 70005.XML для русскоязычной версии, и 440005.XML для англоязычной версии:

  <?xml version="1.0" encoding="UTF-8" ?>

- <language id="7">

- <page id="2010" title="Script Cmd Names" descr=" ">

  <t id="315">Мой патрульный скрипт</t>

  </page>

- <page id="2011" title="Script Cmd Shorts" descr=" ">

  <t id="315">МойПатруль</t>

  </page>

 - <page id="2022" title="Command Info" descr=" ">

  <t id="315">Эта команда запускает патрульный скрипт</t>

  </page>

</language>

Создав этот файл, нам необходимо обеспечить его загрузку при инициализации игры. Для этого мы должны написать инициализирующий скрипт, который выполнит все необходимые подготовительные действия и добавит новую команду в меню. Назовем этот скрипт init.NewCommand. Теперь нам необходимо обеспечить загрузку созданного нами языкового файла. Соответственно первой строчкой в этом скрипте мы должны поставить команду load text: id=5

001   load text: id=5

Эта команда подгрузит созданный нами языковой файл 70005.XML и добавит изменения в основной языковой файл.

Шаг 3. Добавление в меню новой команды и установка связи со скриптом.

Этим шагом мы добавим в выбранное нами меню новую строку и установим ее связь со скриптом patrol.script.xml.

Первое, что нам нужно сделать, это установить связь между выбранной нами командой и нашим скриптом, делается это при помощи команды global script map: set. Далее, произвести установку класса объектов для которых эта команда будет доступна.

002   $command = COMMAND_TYPE_FIGHT_15
 003   global script map: set: key=$command, class=Большой корабль, race=Player, script='patrol.script', prio=0

Команда в строке 003 установила связь между командой COMMAND_TYPE_FIGHT_15 и скриптом patrol.script и установила доступ к новой команде для кораблей класса большой корабль, но новая строка в командном меню еще не создана.

Теперь, следуя условиям задачи нам нужно настроить фильтр на некоторые типы классов кораблей. Точнее, т.к. мы установили доступ к команде COMMAND_TYPE_FIGHT_15 для кораблей класса «Большой корабль», то в него попали все большие корабли классов М6, М2, М1, TL, а по условиям нашей задачи создаваемая нами команда должна быть доступна только кораблям класса М6 и М2. Соответственно нам следует установить фильтр на корабли класса М1, TL. Сделать это можно при помощи команды global script map: ignore, добавив в инициализирующий скрипт следующие строки:

004   global script map: ignore: key=$command, class=Носитель M1, race=Player
 005   global script map: ignore: key=$command, class=Тяжёлый транспорт TL, race=Player

Теперь, закрыв доступ к нашей команде кораблям класса М1, TL, нам остается выполнить последнее условие: обеспечить доступ к команде только для кораблей на которых установлен «Боевой программный модуль МК1». В этом нам поможет команда set script command upgrade: command=<arg> upgrade=<arg> , именно после обработки этой команды ScE добавит новую командную строку в слот команд «Боевые». В нашем случае добавляем строку следующего содержания в инициализирующий скрипт:

006   set script command upgrade: command=$command  upgrade=Боевой программный модуль Мк.1

007   return null

Вот, собственно мы и выполнили поставленную перед нами задачу. Теперь в слоте командного меню «Боевые» добавлена новая команда «Мой патрульный скрипт».

Следует сказать, еще об одной команде подобной команде set script command upgrade: command=<arg> upgrade=<arg> имеющей гораздо более гибкие возможности и предоставляющей возможность установить более сложный фильтр или произвести еще какие либо проверки прежде чем активировать командную строку. Это команда set script command upgrade: command=<Object Command/Signal> upgrade <Var/Ware> script=<script name> , данная команда позволяет в момент открытия меню запустить проверочный скрипт и в зависимости от возвращаемого им флага разрешить или запретить доступ к новой командной строке. Подробное описание команды и возвращаемых флагов в разделе «Команды ScE» глава «Общие команды». Пример ее использования привожу из своего скрипта «Огненный заслон». Данный проверочный скрипт обеспечивает активацию команды в слоте станции в случае, если к данной станции пристыкован корабль на борту которого находиться «Заказ на установку комплекса «Огненный Заслон» или к станции пристыкован корабль с определенным именем. У данного скрипта обязательно должно быть заготовлено место под один аргумент, данный аргумент будет указывать на объект на котором запускается скрипт и будет передан ScE автоматически, т.ч. если ваш скрипт будет запускаться на станции то вы указываете Перем/Станция, как в примере. И соответственно Перем/Корабль если скрипт рассчитан для корабля и т.д. Автоаргументы мы обсуждали в разделе «ScE» глава «Сигналы».

Arguments

  • 1: station , Перем/Станция , 'station'

Source Text

001
002   $name1 =  read text: page=1 id=1231
003   $ship.ar = $station -> get ship array from sector/ship/station
004   $count =  size of array $ship.ar
005   while $count
006    dec $count =
007    $cur.ship = $ship.ar[$count]
008    $name = $cur.ship -> get name
009    $ware = $cur.ship -> get amount of ware Заказ на установку комплекса "ОГНЕННЫЙ ЗАСЛОН" in cargo bay
010    skip if $name == $name1 OR $ware > 0
011     continue
012    $flag = [CmdConCheck.Available]
013    return $flag
014   end
015
016   $flag = [CmdConCheck.Disabled]
017   return $flag

Далее в строке 002 из языкового файла получается имя объекта для сравнения (естественно оно должно быть предварительно внесено в этот файл), в строке 003 мы получаем массив пристыкованных к нашей станции кораблей. А далее идут проверки пристыкован ли станции корабль имеющий на борту определенный товар (заказ на установку комплекса «ОГНЕННЫЙ ЗАСЛОН») или корабль имя которого соответствует тексту взятому со страницы 1 ID 1231. И возвращается соответствующий флаг, в соответствии с которым, пункт меню будет активирован или останется недоступным.

Последнее, что хотелось бы добавить к выше сказанному, это то, что количество команд в Х2 ограниченно и прежде чем вешать свой скрипт более чем одну команду хорошо продумайте, нет ли возможности реализовать его возможности использую одну командную строку (например использование разных аргументов при запуске.). А так же, не забывайте проверить какие команды используют скрипты уже запущенные в вашей игре, дабы избежать конфликтов скриптов.


ScE

Интерпретатор скриптовых команд (ScE)

Этот раздел содержит информацию о том как в общем устроен интерпретатор скриптовых команд и описываются принципы его работы.

v Многозадачность

Чтобы двигаться дальше - нам необходимо более подробно разобраться с устройством SсE.

Когда вы открываете встроенный в игру редактор скриптов и нажимаете PgDn, перед вами появляется длинный список скриптов - в нем присутствуют все скрипты, хотя бы один раз исполнявшиеся с начала игры. Их имена - в первой колонке списка.

Во второй и третьей колонке вы видите некие числа. Они показывают - сколько экземпляров этого скрипта исполняется в данный момент.

Последняя колонка - число стартов скрипта за все время игры.

Во второй и третьей колонке напротив некоторых скриптов вы можете увидеть довольно большие числа - сотни и тысячи экземпляров скрипта, одновременно присутствующих в памяти SсE. Это наблюдение может натолкнуть вас на ошибочный вывод по поводу многозадачности SсE.

Вынужден разочаровать - подлинная многозадачность в SсE отсутствует.

Присутствует ее подобие - так называемая НЕВЫТЕСНЯЮЩАЯ многозадачность.

Что такое «невытесняющая многозадачность»?

Это механизм, от которого даже многоуважаемая фирма Майкрософт отказалась вот уже девять лет тому назад (с выходом в свет Windows'95). Суть механизма заключается в том, что программа (в нашем случае - скрипт) должна сама себя приостанавливать и таким образом давать возможность выполняться остальным программам.

Чтобы лучше понять систему, представьте себе телефон-автомат. И очередь желающих позвонить. Не вытесняющая многозадачность в таком случае будет выглядеть так: каждый человек звонит, говорит сколько ему позволяет его совесть, вешает трубку и переходит в конец очереди - рассчитывая на то, что у всех в очереди совесть таки имеется.

Если при этом в очереди попадается бессовестный человек (программа, не позволяющая системе прервать себя и дать возможность выполняться другим программам) - очередь замирает и ждет, пока этот негодяй не закончит трепаться (на это время система повисает). В Х2 это может выглядеть следующим образом:

001 while [TRUE]

002 end

Запуск этого скрипта, неминуемо подвесит игру.

Для сравнения, вытесняющая многозадачность - это та же телефонная будка, и при ней - жандарм с секундомером и большой дубиной. Каждому в очереди жандарм дает на разговор определенный отрезок (квант) времени. Успел ты закончить фразу, не успел - на полуслове тебя безжалостно прерывают и передают трубку следующему, а ты переходишь в конец очереди и спокойно ждешь, твердо зная что скоро получишь новый квант времени и, возможно, успеешь сказать следующие два слова.

В SсE жандарма нет. Поэтому скрипты не должны надолго "занимать телефон", иначе игра просто повиснет. Чтобы такого не происходило, в SсE есть ряд команд, при исполнении которых скрипт может быть прерван. Насколько большое значение этому придается показывает хотя бы то, что такие команды имеют специальную отметку - знак '@' перед именем.

Соответственно, программист должен позаботиться о том, чтобы в его скриптах такие команды встречались почаще. Например:

001 while [TRUE]

002 @ wait 10 ms

003 end

Теперь этот скрипт не вызовет зависания игры, а будет исполняться прерываясь в строке 002, давая поработать другим скриптам и задачам.

Рассмотрим имеющиеся в ScE прерываемые команды «@».

Семейство wait

В него входят две команды:

1. wait <длительность паузы> ms

2. wait randomly from <минимальная длительность паузы> to <максимальная длительность паузы> ms

Команды этого семейства приостанавливают выполнение скрипта на определенное время. Вполне логично, что эту паузу заполняют собой другие скрипты. Показатель ms приблизительный. Так как минимальное время ожидания не может быть меньше времени прогонки одного фрейма, то есть чтобы вычислить минимальную задержку нужно взять текущее количество фреймов в секунду и разделить на 1000, получим количество ms за один фрейм это будет минимальное время задержки.

Семейство команд fly

В это семейство входят команды "протяженного действия" из раздела навигационных команд, когда кораблю отдается приказ, исполнение которого может занять какое-то время (и не всегда известно точно - какое). Но во время выполнения этих команд система не будет приостановлена.

Вот их перечень:

1.fly to homebase - корабль отправляется в порт приписки.

2. fly to station <станция> - корабль отправляется на указанную станцию.

3. fly to sector <сектор> - корабль отправляется в указанный сектор.

4. turn turret <номер турели> to <объект:цель> : timeout=<время на выполнение команды> ms - корабль пытается навести указанную турель на цель в течение некоторого времени. Команда возвращает специальный код, по которому можно узнать - удалось ли прицелиться. Если код равен FLRET_FIREFREE - прицелиться удалось и можно стрелять. Если код равен FLRET_TIMEOUT - турель не успела навестись за указанное время. Впрочем, подробный разговор о кодах FLRET у нас далеко-далеко впереди. (Возвращаемые коды FLRET будут рассмотрены далее в Разделе Особенности команд- Команды FLY)

5. attack run on target <объект:цель> : timeout=<время на выполнение команды> ms - корабль совершает атакующий маневр в направлении цели.

6. defensive move : type=<число:тип маневра>, intensity= <число: интенсивность маневра>, timeout=<время на выполнение маневра> ms, avoid object=<объект, вокруг которого строится маневр> - корабль выполняет маневр уклонения от указанного объекта.

7. move to ware object <объект:цель для захвата в трюм> for collecting : timeout=<время на выполнение команды> ms - корабль приближается к объекту на расстояние захвата в трюм.

8. move around <длительность полета> ms - корабль просто некоторое время слоняется в космосе без дела.

9. escort ship <корабль-цель> - корабль начинает сопровождать выбранную цель, не включаясь однако с ней в один строй (formation).

10. escort ship <корабль-цель> : timeout=<длительность сопровождения> ms - то же, что и предыдущая команда, но с ограничением по времени.

11. follow object <объект> with precision <дистанция следования> m - корабль строго следует за объектом, соблюдая дистанцию.

12. follow <объект> with precision <дистанция> m : timeout=<время следования> ms - то же, что и предыдущая команда, но с ограничением по времени.

13. move to position : x=<координата x>, y=<координата y>, z=<координата z>, with precision <погрешность> m - корабль летит куда-нибудь в район указанной точки, останавливаясь от нее не дальше, чем допускает указанная погрешность.

Семейство script calls

На сегодня это семейство включает одну команду :

call script. - Команда вызывает другой скрипт. Может быть вызвана с префиксом START, в этом случае скрипт в котором находится команда call script не дожидаясь окончания вызываемого им скрипта, продолжит работу. Прерываемость данной команды условна и подразумевает наличие в вызываемом скрипте команд «@», в противном случае вызываемый скрипт не прервать.

В дополнение к выше сказанному, есть еще один момент. Есть такой пожалуй наиболее неприятный баг: если какой-то непрерывно выполняющийся кусок скрипта (т.е. между двумя ближайшими прерываемыми командами @) выполняется на протяжении более 200 мс, то игра необратимо повиснет. Это одна из основных причин повисания казалось бы идеально написанного скрипта. Причем, если на быстром процессоре скрипт может отмолотить за 50 мс, это не гарантирует, что на компьютере с более слабым процессором этот же скрипт не подвесит игру. Но это еще не самое страшное. Как известно, весь движок игры есть один единственный процесс, где графика, экономика, скрипты и многое другое выполняется поочередно Итог - стоит дать сбой анимации в интенсивном бою и это незамедлительно отражается на скорости исполнения скриптов. Не вместились в окно 200 мс - и игра повисла. И этот баг не отловишь, т.к. он может иметь место 1 раз за 20 часов игры.

Так что не экономьте на командах wait! Даже "wait 1 ms" здорово помогает избегать подобных инцидентов. Т.е. обязательно внутри любого цикла должен быть "wait 1 ms", если только этот цикл не велик и вы абсолютно уверены, что он завершится при любых обстоятельствах.

v Локальные скрипты, глобальные скрипты

Раньше мы уже обсуждали тот факт, что скрипты бывают локальные и глобальные. С глобальными скриптами мы столкнемся при изучении текста и концепции StationManager. (см. «Описание скриптов пилотов» )

Локальные скрипты отличаются от глобальных тем, что они привязаны к какому-либо объекту. Что значит "привязаны"? Это значит, что в момент уничтожения объекта все эти скрипты будут остановлены. Также это значит, что внутри этих скриптов обсуждавшаяся ранее константа [THIS] будет указывать на объект, к которому скрипты привязаны.

Еще одно отличие локальных скриптов заключается в том, что каждому локальному скрипту при запуске назначается номер задачи (Task ID) и приоритет (prio). Когда в игре активирован редактор скриптов, вы можете просмотреть информацию обо всех задачах, присутствующих на каком-либо объекте, через меню информации об объекте (кнопка I). Просто нажимайте PgDn - и ниже общих свойств объекта вы увидите список стеков задач. Вы увидите общую информацию по каждому стеку и список находящихся в стеке скриптов.

v Задачи, стеки, приоритеты

Каждый объект в игре можно образно представить себе в виде библиотечной картотеки. Картотека - это набор ящичков с буковками алфавита. В каждом ящичке лежит стопочка карточек с названиями книг, начинающимися на ту самую букву алфавита что написана на ящичке. Карточки в ящичке тоже отсортированы - но уже по второй букве названия (у всех карточек из одного ящичка первая буква названия одинаковая).

Так вот, в нашем случае картотека - это объект. Ящички маркированы не буквами, а числами. Эти числа называются номерами задач, а ящички - стеками задач. Карточки - это скрипты. Номер задачи скрипта показывает, в каком стеке скрипт будет исполняться (в какой ящичек ляжет карточка).

Если для запуска локального скрипта мы используем команду start call script <скрипт> или start task <число:номер задачи> with script <скрипт> and prio <число:приоритет>, из ящичка будут безжалостно вытряхнуты все находящиеся в нем карточки (будут уничтожены все скрипты в стеке задачи) и вместо них в ящичек будет помещена одна-единственная карточка (будет запущен указанный скрипт). Однако имеет место одна оговорка, команда @ START [THIS]->call script ничего не вытеснит и не запустит, а просто подвесит текущий скрипт, если он работает в стеке Task 0. Если же запустить call script без префикса START и на отличном от текущего объекте, то она тоже вытеснит все из стека Task 0 этого объекта.

Если для запуска локального скрипта мы используем команду interrupt task <число:номер задачи> with script <скрипт> and prio <число:приоритет>, то скриптовый движок сначала сравнит приоритеты нового скрипта и того, который в данный момент исполняется в указанном стеке. Если приоритет нового скрипта больше (причем строго больше) приоритета уже исполняющегося - исполняющийся скрипт будет приостановлен и "поверх" него запустится новый скрипт. Старый скрипт при этом никуда не денется и будет смирно ждать пока не завершится новый скрипт, с более высоким приоритетом (или пока весь стек не будет "зачищен" командой start task). Иными словами, приоритет - это вторая буква в названии книги на карточке. Если в ящичке уже лежит стопка карточек, то мы сможем добавить в него только такую карточку, название которой идет по алфавиту следующим за названием с верхней карточки в стопке.

Таким образом, в стеке задачи может лежать несколько скриптов. Активным (работающим) будет только самый последний, остальные скрипты в стеке задачи будут "заморожены".

Это очень удобный механизм для моделирования реакций на окружающую обстановку.

Например, предположим, на объекте (транспортном корабле), в стеке с номером 0, исполняется скрипт, ведущий корабль на торговую станцию за товаром. И в процессе полета возникает необходимость отбиться от пиратов.

Если бы не было стекового механизма, нам следовало бы сначала запомнить что мы делали (куда и зачем летели), где-то сохранить эту информацию, затем остановить текущий скрипт полета, затем запустить скрипт обороны от нападения, затем вновь вспомнить чем мы занимались до нападения (куда и зачем летели) и снова запустить скрипт полета к цели.

Стековый механизм позволяет нам просто запустить в том же стеке (с номером 0) скрипт обороны с приоритетом большим, чем приоритет скрипта полета к цели. Тогда скрипт полета будет автоматически "заморожен" и автоматически же "разморожен" в момент окончания "боевого" скрипта.

v "Волшебные" номера задач

Номера ящичков-задач могут идти не подряд и не с начала, то есть на объекте могут существовать, к примеру, задачи с номерами 2, 5 и 999999.

Почти все задачи равноправны, но есть несколько специальных задач с особыми номерами и особым назначением исполняющихся в них скриптов.

Задача 0 (Task 0) на объектах-кораблях служит для запуска скриптов автопилота. Все действия, которые вы назначаете кораблю через основную командную консоль, отрабатываются скриптами в нулевом стеке. Все поступающие кораблю сигналы также отрабатываются в этом стеке (о сигналах поговорим чуть позже).

Задачи 1-6 (Task 1-Task 6) на объектах-кораблях служат для запуска скриптов управления турелями больших кораблей. Номер задачи соответствует номеру турели в консоли управления турелями.

Задачи 10 и 11 (Task 10, Task 11) на объектах-кораблях соответствуют двум введенным в версии 1.4 дополнительным слотам для команд. Команды для первого слота отрабатываются в десятом стеке, команды для второго слота - в одиннадцатом.

Задачи 10-19 (Task 10 - Task 19) на объектах-станциях соответствуют десяти введенным в версии 1.4 командным слотам станций игрока. Команды для первого слота отрабатываются с десятом стеке, команды для второго слота - в одиннадцатом стеке и так далее.

v Прерывания.

Иногда в определенной игровой ситуации, может потребоваться чтобы ваш скрипт запущенный на объекте и выполняющий какую либо задачу прервался и на некоторое время передал управление другому скрипту, который в свою очередь отработав, вернул управление прерванному скрипту. Например, ситуация когда сектор патрулирует несколько кораблей объеденных в группу, т.е. подчиненные корабли сопровождают корабль лидер. Если лидер совершает прыжок в другой сектор, то сопровождающие корабли должны временно прервать выполнение сопровождения и совершить прыжок в след за лидером, а после прыжка вернуться к сопровождению. В ScE для выполнения подобных действий предусмотрены две команды. Первая из них это call script эта команда безусловно прервет выполнение текущего скрипта до тех пор, пока вызываемый скрипт не закончит работу. Эта команда удобна в случае необходимости прервать выполнение текущего скрипта в не зависимости от выполняемых в данный момент задач в частности их приоритетов. Вторая команда interrupt with script позволяет прервать текущий скрипт в случае если приоритет вызываемого скрипта выше приоритета вызывающего скрипта (более подробно использование приоритетов будет рассмотрено в следующей главе «Сигналы»). Кроме того, эта команда не прерывает текущий скрипт сразу, а лишь помещает его в очередь на выполнение и прерывание будет произведено на первой встреченной команде со знаком «@».

Для демонстрации используем два небольших скрипта. В первом рассмотрим команду call script :

Скрипт CallScript.xml

001   write to log file #1  append=[TRUE]  value='CALLSCRIPT string 001'
002 @ = [THIS] -> call script 'temp' :
003   write to log file #1  append=[TRUE]  value='CALLSCRIPT string 003'
004   return null

Вспомогательный скрипт temp.xml

001   write to log file #1  append=[TRUE]  value='TEMP string 001'
002 @ = wait 10 ms
003   write to log file #1  append=[TRUE]  value='TEMP string 003'
004   return null

Выполнив скрипт CallScript смотрим порядок выполнения в лог файле log0001.txt:

CALLSCRIPT string 001

TEMP string 001

TEMP string 003

CALLSCRIPT string 003

Из примера видно, что CallScript был прерван в строке 002, далее полностью отработал скрипт temp и после завершения управление было возвращено CallScript в стоку 003. Теперь давайте рассмотрим команду interrupt with script:

Скрипт INTERRUPT

001   write to log file #1  append=[TRUE]  value='INTERRUPT str 001'
002   [THIS] ->  interrupt with script 'temp' and prio 1000:  arg1=null arg2=null arg3=null arg4=null
003   write to log file #1  append=[TRUE]  value='INTERRUPT str 003'
004 @ = wait 1 ms
005   write to log file #1  append=[TRUE]  value='INTERRUPT str 005'
006   return null

В итоге мы получаем запись в логе:

INTERRUPT str 001

INTERRUPT str 003

TEMP string 001

TEMP string 003

INTERRUPT str 005

Что говорит о том, что скрипт INTERRUPT начав работать выполнил соку 001, во второй стоке в очередь на выполнение был поставлен скрипт temp, но его выполнение не началось, а было продолжено выполнение скрипта INTERRUPT строка 003. В стоке 004 встречена команда со знаком «@», здесь выполнение скрипта INTERRUPT прерывается и полностью выполняется скрипт temp. По окончании работы скрипт temp возвращает управление INTERRUPT в строку 005. Следует заметить, что прерывание произошло т.к. приоритет скрипта temp мы установили как 1000, в то время как приоритет INTERRUPT равен 0, но если приоритет вызывающего скрипта был бы выше, то прерывание не произошло бы. В ситуации если приоритет вызывающего скрипта был повышен после того как вызываемый скрипт был помещен в очередь, т.е. после команды interrupt with , то прерывание все равно произойдет и вызываемый скрипт будет полностью выполнен. Так же при использовании данной команды следует учитывать тот факт, что если после команды interrupt with нет ни одной команды со знаком «@» то прерывания скрипта не произойдет.

v Сигналы.

В Х2 имеется специальная группа прерываний называемая сигналами. Понятие сигнал в ScE подразумевает, прерывание выполняемого скрипта специальным прерыванием сформированным в случае возникновения в игре определенных условий, самим ScE. Например, если корабль атакован другим кораблем, то для атакованного корабля ScE сформирует сигнал SIGNAL_ATTACKED. Данный сигнал, прервет скрипт выполняемый в нулевом стеке на атакуемом корабле в данный момент и передаст управление специальному скрипту обработчику сигнала, который в свою очередь будет выполняться в этом же стеке. Прерывание произойдет только при условии, что приоритет скрипта обработчика выше приоритета скрипта выполняемого в данный момент на объекте, в противном случае сигнал будет проигнорирован. После обработки сигнала, скрипт обработчик вернет управление скрипту, который выполнялся на корабле до прерывания. Сам процесс прерывания происходит по принципу «не вытесняющей многозадачности», т.е. выполняемый скрипт будет прерван не мгновенно по поступлению сигнала, а на первой же команде со значком «@». Это еще один аргумент в пользу размещения в ваших скриптах команд задержек.

Сигналы в Х2 делятся на две группы, это синхронные сигналы и асинхронные. Разделение на группы происходит в зависимости от момента генерации сигнала. Различия заключаются в следующем:

Синхронные сигналы – это прерывания генерируемые ScE, непосредственно в момент наступления определенных условий. Точнее можно сказать, это прерывание формируемое синхронно наступлению определенных условий в игре. Например, в момент гибели корабля ScE сформирует сигнал SIGNAL_KILLED, но в момент возникновения данного сигнала, корабль еще существует и ScE будет ожидать пока не закончит свою работу скрипт-обработчик данного сигнала, хотя все игровые показатели данного объекта будут говорить о том что он уничтожен (нулевой щит и корпус). И только после того как обработчик вернет управление (return null), ScE продолжит выполнять процедуры связанные с уничтожением объекта, как то, анимационный эффект взрыва, удаление из памяти ссылок на уничтоженный объект и удаление самого объекта из галактики Х. Все эти процессы проходят за считанные миллисекунды и не заметны играющему, но скриптописатель должен учитывать данные нюансы при создании собственных скриптов изменяющих стандартные скрипты-обработчики сигналов. В Х2 очень легко нарушить некий баланс имеющийся в игре, что не минуемо отразится на играбельности в целом.

Асинхронный сигнал – это прерывание сформированное ScE по прошествии определенных игровых условий, т.е этот сигнал будет передан после того как событие выполнившие заданные условия произошло. Примером асинхронного сигнала может послужить сигнал SIGNAL_ATTACKED. Данный сигнал формируется после того как объект был атакован, то есть после того как выстрелы атакующего объекта достигли цели и ScE уже произвел соответствующее снятие щита и корпуса у атакованного объекта и воспроизвел все анимационные эффекты. Соответственно, ScE не приостанавливается при обработке асинхронных сигналов для ожидания момента когда скрипт-обработчик сигнала вернет управление как это происходит при генерации и обработке синхронных сигналов. А выполнив все необходимые процедуры, формирует сам сигнал, который в свою очередь запускает соответствующий скрипт обработчик.

Теперь рассмотрев виды сигналов, следует оговорить еще одну особенность их формирования движком Х2. Для этого мы используем понятие «автоаргумент». Под этим понятием я подразумеваю следующее:

Автоаргумент – это набор данных сформированный самим ScE при генерации определенного сигнала. Эти аргументы будут переданы скрипту–обработчику сигнала автоматически и в определенном порядке без какого-либо дополнительного участия самого программиста.

Какие данные передавать скрипту, прописано самом движке Х2 и изменить их стандартными путями невозможно. Но можно воспользоваться теми данными что уже есть. Для этого необходимо при написании скрипта-обработчика в полях аргументов заготовить места под них, а ScE при формировании сигнала сам сгенерирует нужные данные. Данные будут переданы в определенном порядке, соответственно и аргументы должны быть расположены в таком же порядке. Стандартные автоаргументы формируемые для сигналов и их порядок описан в таблице.

Всего ScE Х2 формирует семь видов сигналов, для каждого из них назначен стандартный скрипт-обработчик, который задается при запуске игры или загрузке сейва. Изначально, в игре за назначение обработчиков сигналов, отвечает служебный скрипт !init.ship.globalscriptmap.std.xml, находящийся в папке \scripts. !init.ship.globalscriptmap.std.xml вызывается из основного инициализирующего скрипта !init.ship.globalscriptmap.xml, это основной инициализирующий скрипт осуществляющий инициализацию всех установок заданных по умолчанию. Далее, в процессе игры, пользователь может при помощи собственных скриптов сам переназначить скрипт обработчик. В таблице указаны все имеющиеся в игре сигналы и заданные им в !init.ship.globalscriptmap.std.xml, скрипты обработчики.

Сигнал | Тип сигнала Синх \ Асинх | Условие возникновения | Автоаргументы | Стандартный скрипт-обработчик | Приоритет по умолчанию
SIGNAL_ATTACKED | Асинх. | Объект атакован. Выстрелы атакующего достигли цели. | 1. The attacker – тип данных <Ship\Station>, нападающий объект. 2. action – тип данных <var\number> возвращается код текущей операции выполняемой объектом. В стандартном обработчике используются коды [ACTION_LAND_IN_STATION] посадка на станцию и [ACTION_ENTER_GATE] входит во врата. | !ship.signal.attacked (для кораблей класса «Корабль») !ship.signal.attacked.ts (для корабле класса «легкий транспорт TS») !station.signal.attacked.pl (для станций) | 100
SIGNAL_COLLISIONWARN |  |  |  | Данный сигнал не работает. |
SIGNAL_LEADERNEEDSHELP | Асинх. | Сигнал сопровождающему кораблю – лидер атакован | 1. <Var\Ship> указатель на корабль требующий помощи. 2. <Value> атакующий объект | !ship.signal.leaderneedshelp | 150
SIGNAL_FOLLOWERNEEDSHELP | Асинх. | Сигнал лидеру – сопровождающий атакован | 1. <Var\Ship> указатель на корабль требующий помощи. 2. <Value> атакующий объект | !ship.signal.followerneedshelp | 150
SIGNAL_ FORMATIONLEADERCHANGED | Асинх. | Сигнал для всей группы сопровождающих кораблей – лидер изменился (например: предыдущий лидер убит) | 1. <Var\Ship> Новый лидер формации. | !ship.signal.formationleaderchg (скрипт -пустышка) сигнал обрабатывается на уровне движка. | 200
SIGNAL_CAPTURED | Синхр. | Объект захвачен |  | !ship.signal.captured | 300
SIGNAL_KILLED | Синхр. | Объект уничтожен | 1. <Value> объект убийца. 2. <ObjectCommand> текущая команда объекта 3. <value> Основная цель команды 4. <value> Вторая цель команды 5. <value> Первый параметр выполнявшейся команды 6. <value> Второй параметр выполнявшейся команды | !ship.signal.killed – для всех объектов. | 10000

Для того, чтобы понять как это работает, давайте попробуем создать небольшой скрипт наглядно демонстрирующий работу сигналов. Рассматривать будем работу сигнала SIGNAL_ATTACKED (его легче всего получить, достаточно обстрелять объект не принадлежащий игроку. Обратите внимание на то, что данный сигнал не формируется при обстреле объектов той же расы что и нападающий). И так, суть нашего скрипта, это эмуляция некого парализующего эффекта длящегося одну минуту, у обстрелянного корабля относящегося к классу «легкий транспорт TS» и принадлежащего расе аргон, а также вывод названия атаковавшего объекта в бортовой журнал.

Создаем свой скрипт обработчик, назовем его signal.ATTACKED

Script signal.ATTACKED

Version: 0
for Script Engine Version: 25

Description

New associated script SIGNAL ATTACKED

Arguments

1: Attacker, Var/Ship/Station, ‘the attacker’

Source Text

 001   $cont = 3
 002   while $cont
 003 @  = wait 100 ms
 004    play sample 1114
 005    dec $cont =
 006   end
 007   write to player logbook $Attacker
 008 @ = wait 60000 ms
 009   return null

001-006 организуем воспроизведение звукового сигнала похожего на бряканье ложки в пустой кружке, это сообщит нам о том, что произошло прерывание вызванное поступлением сигнала SIGNAL_ATTACKED и в данный момент работает созданный нами обработчик этого сигнала.

007 запишем в бортовой журнал переменную $Attacker которая в данный момент содержит указатель на атакующий объект, т.е. на наш корабль. Значение в эту переменную было внесено самим движком, когда был сформирован сигнал. Это пример использования автоаргументов.

008 собственно и есть, сама эмуляция одноминутного паралича у корабля получившего сигнал.

009 возвращаем управление прерванному сигналом скрипту.

Для того, чтобы наш скрипт назначить обработчиком, нам потребуется еще один скрипт который переназначит стандартный скрипт обработчик на нужный нам. Назовем его, init.ATTACKED.signal :

Script init.ATTACKED.signal

Version: 0
for Script Engine Version: 25

Description

Init associated script SIGNAL ATTACKED

Arguments

Source Text

 001   * Назначаем новый обработчик сигнала SIGNAL_ATTACKED
 002   global script map: set: key=SIGNAL_ATTACKED, class=Лёгкий транспорт TS, race=Аргон, script='signal.ATTACKED', prio=100
 003   return null

Теперь перезагружаем сохраненку или воспользуемся командой из главного меню редактора «Reinit Script Caches», т.к. наш инициализирующий файл имеет имя формата init.*.*, то он загрузится в память автоматически при использовании любого из вышеуказанных способов. Теперь, вылетаем в космос на любом корабле имеющем хоть одну пушку и ищем любой аргонский транспорт класса TS. Подлетаем к нему на расстояние выстрела, смотрим информацию о нем. Нас интересует служебная информация о скриптах выполняемых на этом корабле в данный момент:

Как мы видим, в стеке нашего подопытного объекта, находиться три скрипта (на вашем объекте может выполняться другой набор скриптов, в нашем случае это не имеет особого значения). Фактически, это процесс выполнения команды «Купить товар». Теперь, обстреляйте корабль (не убейте, а только обстреляйте), стреляйте одиночными выстрелами пока не услышите звуковой сигнал издаваемый нашим скриптом обработчиком. Как только это произошло, вы увидите, что транспорт остановился и завис в космосе. Открываем информационный экран:

Как мы видим, в стек добавился еще один скрипт. Это назначенный нами обработчик сигнала SIGNAL_ATTACKED и т.к. приоритет для нашего скрипта обработчика, мы назначили как 100 ( в init.ATTACKED.signal, строка 002), а все выполняемые на объекте в нулевом стеке имеют приоритет 0, то наш скрипт обработчик signal.ATTACKED будет добавлен в конец нулевого стека и ему будет передано управление. Так как, практически после каждого попадания по объекту ScE будет генерировать сигнал SIGNAL_ATTACKED, то установка приоритета для скрипта обработчика является своеобразной блокировкой от прерывания уже выполняемого в данный момент обработчика. Прерывание будет возможно только в том случае, если выполняемый в данный момент скрипт обработчик сам понизил свой приоритет или обработчик поступившего сигнала имеет более высокий приоритет.

Наличие сигналов-прерываний в ScE и возможность изменения скриптом собственного приоритета, предоставляет возможность гибкого управления реакциями объекта на внешние условия, используя для выполнения разных действий сам скрипт обработчик. Эта возможность наглядно реализована в стандартном скрипте обработчике сигнала SIGNAL_ATTACKED для кораблей класса «легкий транспорт TS» - скрипт !ship.signal.attacked.ts. Давайте разберемся как работает этот скрипт. Не буду описывать сам скрипт, а лишь логику построения процедур.

001
 002   * front mounted lasers
 003   $frontlasers = [THIS] -> get max. number of lasers in turret 0
 004   $maxlaserst = [THIS] -> get maximum laser strength
 005   $frontmaxlaserst = [THIS] -> get max laser strength in turret 0
 006
 007   $random = random value from 0 to 100 - 1
 008
 009   if [THIS] != [PLAYERSHIP] AND ( $random < 30 OR [OWNER] == Player )
 010    $r = random value from 5 to 11 - 1
 011    $r = [THIS] -> launch $r fight drones: protect me or attack target=null
 012   end
 013
 014   if $action == [ACTION_LAND_IN_STATION] OR $action == [ACTION_ENTER_GATE]
 015    return null
 016   end

Проверяем некоторые условия. Если текущий объект не корабль игрока и еще кое-какие условия с элементом случайности, то запускаем Дронов для защиты. Проверяем не запущена ли в данный момент процедура стыковки или входа во врата, если запущена возвращаем управление скрипту, прерванному поступлением сигнала. Если ни какие условия не совпали, продолжается выполнение скрипта.

017
018   * try to attack
019   $sobj = [THIS] -> get SectorObject ID
020   if not is script with prio 50 on stack
021    if ( [OWNER] == Player AND $sobj == 0 ) OR ( $random < 20 AND $frontlasers AND $frontmaxlaserst )
022 @   skip if not [THIS] -> call script '!ship.signal.attacked' :  the attacker=$attacker  action=$action
023      return null
024    end
025   end
026
027   if $sobj
028    $speed = [THIS] -> get max speed
029    $attackerspeed = $attacker -> get max speed
030    if $speed <= $attackerspeed OR $random > 80
031     $r = random value from 40 to 90 - 1
032     $timeout = random value from 20000 to 40000 - 1
033 @   $r = [THIS] -> defensive move: type=null, intensity=$r, timeout=$timeoutms, avoid object=$attacker
034    end
035   end

Проверяем не убегает ли в данный момент наш объект от агрессора (наличие в нулевом стеке скрипта с приоритетом 50, откуда он мог взяться будет понятно далее по рассмотрению скрипта). Если «нет», то в зависимости от условий (наличие пушек, принадлежность, элемент случайности), либо запускаем скрипт для атаки объекта-агрессора, либо выполняем маневр уклонения. Если ни какие условия не совпали, продолжается выполнение скрипта.

036
 037   * try to fly to nearest station only if not already done...
 038   if not is script with prio 50 on stack
 039    if not is script with prio 99 on stack
 040     if $random < 40 AND [OWNER] != Player
 041      $flags = [Find.Friend] | [Find.Neutral] | [Find.Nearest]
 042      $station =  find station: sector=[SECTOR] class or type=null race=null flags=$flags refobj=[THIS] maxdist=null maxnum=null refpos=null

Еще раз в строках 038 и 039 осуществляется проверка не убегает ли объект от агрессора или не атакует ли его. Все эти проверки осуществляются при помощи работы с приоритетами, которые выставляют скрипты выполняющие соответствующие задачи. Если нет, учитываем некую случайность (переменная $random) и если данный объект не принадлежит игроку, ищем ближайшую дружественную или нейтральную станцию.

043      if $station
044   * run the flee to station part with prio 50
045       set script priority to 50
046 @     = [THIS] -> call script '!ship.sh.attack.ts.flee' :  the attacker=$attacker  station to dock at=$station
047       return null
048      end
049     end
050    end
051   end
052
053   return null

Если станция найдена, то понижаем приоритет скрипта со 100 до 50 и запускаем механизм бегства на ближайшую найденную станцию, используя вспомогательный скрипт !ship.sh.attack.ts.flee с указанием атакующего объекта (автоаргумент) и выбранную для бегства станцию. Теперь, если во время полета к станции объект снова получит сигнал SIGNAL_ATTACKED, то он не прекратит бегства к станции, а выполнив маневр уклонения продолжит полет к ней. Точно также, при совпадении условий в сегменте 018-025, будет запущен скрипт атаки, который в свою очередь установит свой приоритет как 99 и в случае поступления сигнала SIGNAL_ATTACKED обработчик учтет наличие в стеке скрипта выполняющего атаку.

Для полного понимания этого материала, попробуйте разобрать работу других скриптов обработчиков, это скрипты с именами !ship.signal.*. И поэкспериментируйте в игре, создавая для подопытных объектов условия в которых для них будут генерироваться те или иные сигналы. Просматривая какие скрипты находятся в нулевом стеке и как у них изменяются приоритеты, разобраться не составит труда.


Описание редактора скриптов "Х2 The Threat"

Описание редактора скриптов "X2 The Threat" .

При первом запуске редактора мы видим сообщение от Егософт о том что запущен интерфейс ручного управления бортовым компьютером и краткую справку по использованию основных «горячих» клавиш. Нажимаем ENTER и попадаем в главное меню редактора содержащее следующие пункты:

Из этого меню осуществляется весь процесс контроля исполнения и отладки НС.

v Редактор скриптов

Выбрав этот пункт в главном меню редактора вы переходите к браузеру скриптового редактора, то есть к списку скриптов доступных для редактирования, выполнения и т.п. Самая верхняя строка из списка, это «новый скрипт», позволяет приступить к созданию нового НС. Если вы выберете ее, то редактор спросит у вас имя нового скрипта, и создаст пустой скрипт-файл. Браузер скриптового редактора позволяет производить над скриптами определенные действия, такие как копирование, удаление, выполнение и т.д. В таблице приведены клавиши управления скриптовым редактором:

Клавиши управления редактором скриптов:
Режим браузера скриптов:
<l> |  | загрузить скрипт из папки скриптов
<c> |  | копировать скрипт
<r> |  | выполнить скрипт
<Del> |  | удалить скрипт
<Enter> |  | редактировать скрипт
Режим редактора скриптов:
<вверх/вниз> | перемещение по строкам
<влево/вправо> | перемещение между выражениями
<Enter> | меню функций
<Ins> | вставить новую строку
<Del> | удалить строку
<c> | копировать строку в буфер
<x> | вырезать строку в буфер
<v> | вставить строку из буфера
<.> | закомментировать строку
<,> | удалить символ комментария
<Home> | вставить операнд выражения
<End> | удалить операнд выражения
<Esc> | сохранить и закрыть скрипт

v Reinit Script Caches

При запуске игры все НС запускающиеся из командного меню помещаются в специальный СкриптКэш. Это делается для более быстрого выполнения команд. Но, данный подход имеет и другую сторону, ScE будет использовать старую версию скрипта даже после его модификации и перезапуска команды. Пункт меню Reinit Script Caches производит перезагрузку СкриптКэша, то есть все скрипты привязанные к пунктам меню будут перезапущены. Однако обратите внимание на то, что изменения не будут действовать для объектов уже выполняющих данную команду, а только для тех которым команда отдается после перезагрузки СкриптКэша. Для того чтобы изменения вступили для этих объектов следует остановить выполнение команды и отдать ее снова.

v Script Debugging

Переключатель режимов отладки НС на объекте. Имя объекта указывается в этой же строке. Здесь возможны два варианта: вести пошаговую отладку (Trace) или производимые НС действия будут записываться в лог (Log). Выбор осуществляется нажатием “Enter”, при установке курсора на эту строку.

v Clear Debug Messages

Выбор этого пункта, удалит все данные из лога объекта указанного в Script Debugging.

v Script Debugger Menu

Просмотр лога отладки или пошаговое выполнения НС с показом значений переменных.

Просмотр лога (Log)– при установленном в это положение переключателя Script Debugging будет отражен лог, наполнение которого происходит в реальном времени, по мере выполнения команд НС на данном объекте. Чтобы было более понятно создадим небольшой скрипт с именем a.missile.fire :

001 $ware = Ракета Москит | // раздел общие команды. <RetVar/IF> <Expression> Присваиваем переменной $ware значение Ракета Москит
002 $count = 20 | // Присваиваем переменной $count=20 раздел общие команды <RetVar/IF><Expression>
003 while $count | // запускаем цикл с условием $count не ноль. Раздел общие команды. <RetVar/IF><Expression>
004 @ = wait 3000 ms | //Ожидаем 3 секунды (чем больше в цикле таких команд тем стабильней работает игра см.Многозадачность).Раздел общие команды.
005 dec $count = | // Цикл начал выполнение, уменьшаем счетчик витков на 1. Раздел общие комманды.
006 $victium = get player tracking aim | // получаем объект в прицеле корабля игрока в переменную $victium. Раздел «навигационные команды»
007 = [PLAYERSHIP] -> add 1 units of $ware | // добавляем одну ракету в трюм корабля игока Раздел «Торговые команды»
008 = [PLAYERSHIP] -> fire missile $ware on $victium | // выпускаем одну ракету по $victium Раздел навигационные команды
009 @ = wait 3000 ms | // ждем 3 сек.
010 end | // начинаем новый виток цикла, то есть передаем управление в строку 003. Раздел «Общие команды=>команды исполнения.
011 return null | //возвращаем управление вызывающему скрипту

* для тех кто плохо знаком с расположением команд в комментариях указаны разделы где они расположены.

Этот скрипт производит двадцать выстрелов ракетой Москит по объекту находящемуся в прицеле корабля игрока (наличие ракет в трюме не обязательно), этого времени нам хватит чтобы рассмотреть работу Script Debugger Menu. Войдите в скриптовый редактор, <Shift-C>, выберете Редактор скриптов=> новый скрипт, введите имя и повторите текст данного скрипта. Сохраните его. После, выйдите из редактора и подлетите на своем корабле к какому-нибудь астероиду. Остановитесь и возьмите его в прицел, нажмите «Т» чтобы прицел зафиксировался на астероиде (Важно: проверьте чтобы для турелей не было установлено никаких команд, если они установлены отключите их). Теперь возвращайтесь в редактор выбирайте в списке скриптов созданный a.missile.fire и жмите «r». На запрос редактора об объекте выбираем собственный корабль и жмем “Enter” Через три секунды ваш корабль сам выстрелит ракетой по астероиду. Если это произошло, снова запускаем редактор скриптов, если нет, то проверяем последовательность действий описанную выше. Наш корабль выстрелил, и мы вернулись в главное меню редактора. Очищаем буфер ScE от возможных остатков старых данных выбором команды Clear Debug Messages и устанавливаем переключатель Script Debugging в позицию “Log” и вызываем пункт Script Debugger Menu. В открывшемся окне видим длинный и все время пополняющийся табличный список:

Строки с 1 по 9 содержат в (правой части) исходный текст нашего скрипта, после этого листинг начинает дублироваться, а если посмотреть параметр Line:, вы заметите, что цифры совпадают с номерами строк исходного текста скрипта, и до строки 9 последовательность сохранялась, а в десятой снова стал равен 3. Если посмотрим какие операторы стоят в этих строках, то становиться ясно что в строке 9 мы дошли до конца цикла и передали управление в строку 3, так как в листинге нашего скрипта в строке 10 стоит оператор end, а в данном случае он передает управление в начало цикла в строке 3. Теперь как и задумывалось данный сегмент нашего скрипта исполнится двадцать раз. Соответственно и в логе он будет последовательно отображен двадцать раз, после чего скрипт завершится и по команде return передаст управление взывающему скрипту, а в нашем случае т.к. мы вызывали скрипт в ручную и у нашего корабля не было никаких других команд корабль перейдет в режим ожидания, а в лог больше ничего записываться не будет до тех пор пока корабле не будет снова запущен какой либо скрипт.

Теперь кратко опишем остальные данные выводимые в строке:

Script Name – имя скрипта, команда которого была выполнена в данной строке.

Line – номер строки в скрипте Script Name.

Stackdepth – глубина стек в котором выполняется задача (количество скриптов в стеке отсчет ведется с 0)

Prio – приоритет выполняемого скрипта

PID – глобальный идентификатор задачи

TaskID – Идентификатор задачи

Command – исходный текст команды

Теперь перед нами вся последовательность команд выполненная ScE при обработке скрипта a.missile.fire.

Пошаговое выполнения (Trace) - это второй вариант отладки скрипта, пошаговое выполнение команд подразумевает следующее, ScE выполнив одну команду ожидает разрешения от пользователя на выполнение следующей, при этом показываются значения всех переменных этого скрипта. Для подробного рассмотрения этого режима выполним такие же подготовительные действия как и при рассмотрении режима «Log», с той разницей что переключатель Script Debugging переведем в состояние «Trace» и запустим скрипт a.missile.fire. Выполняем пункт меню Script Debugger Menu. Окно для пошаговой отладки состоит из двух сегментов:

Верхний сегмент показывает листинг уже выполненных команд (отражены белым цветом), и команда ожидающая от пользователя разрешения на выполнение (отражена зеленым цветом). Информативное содержание строки такое же, как и в режиме «Log» (Script Name: Line: Stackdept:…). Если вы нажмете Enter, то команда ожидающая разрешения выполнится и изменит цвет на белый, а ниже появится следующая команда из выполняемого скрипта и редактор будет ожидать следующего нажатия Enter. Нижний сегмент показывает список всех переменных, которые использует скрипт. Имя переменной указывается самым первым (Variable Name), далее идет тип данных (Data Type) и значение (Value). Изначально тип данных всех переменных NULL и изменяется он только после того как переменной было присвоено какое то значение. Само значение переменной отражается сразу за типом данных.

Пошаговый режим удобен для поиска ошибок в проблемных скриптах.

v Global Script Tasks

Этот пункт меню служит для того чтобы можно было посмотреть какие глобальные скрипты выполняются в данный момент, а также для удаления из памяти не нужных (нажатие «Del»). Для рассмотрения используем тот же скрипт a.missile.fire, только выполним его как глобальный, то есть без привязки к какому либо объекту, для этого на вопрос при запуске вместо выбора объекта выбираем null. Если скрипт запущен, выбираем Global Script Tasks. Открывается окно содержащее листинг всех скриптов выполняющихся глобально и среди них должен присутствовать запущенный нами скрипт a.missile.fire. Присутствие запущенного нами скрипта в списке говорит о том, что в данный момент наш скрипт a.missile.fire выполняется как глобальный. Если выйти из редактора, то мы увидим, что наш корабль стреляет ракетами по астероиду.

Теперь давайте попробуем удалить наш скрипт из память (прервем его исполнение). Возвращаемся в скриптовый редактор в раздел Global Script Tasks. Выбираем наш скрипт в списке и нажимаем «Del», на запрос об удалении скрипта отвечаем «Да». Теперь наш скрипт исчез из списка выполняемых глобально скриптов, а корабль соответственно перестал стрелять и замер в ожидании следующих команд.

Данные о скрипте выводимые редактором в Global Script Tasks:

PID – глобальный идентификатор задачи

Script Name – имя глобального скрипта

RefObject – ???


Советы бывалого скриптописателя

v Как выходить в Windows из игры.

Когда вы будете учиться писать скрипты, а деле отлаживать свои собственные, то вам обязательно понадобиться периодически выходить из игры в Windows. Существует несколько способов, здесь, они будут описаны. А вы выберите тот который вам подойдет лучше всего.

Первый способ – Находясь в игре (полноэкранный режим) нажать ALT+CTRL+DEL. Эффект не мгновенный. Через пару секунд откроется виндосовский диспетчер задач, а игра свернется. Способ достаточно медленный, но удобен тем, что выходит в виндовс сто процентно.

Второй способ – более быстрый (для полноэкранного режима, требуется, чтобы в виндовс помимо Х2 выполнялась еще какая нибудь задача). Нажимаем ALT+Tab и выходим. Но для отладки, всетаки не удобен.

Третий способ – на мой взгляд самый эффективный. Запускаем в виндовс любую задачу (например Блокнот), и запускаем Х2 в оконном режиме. Выход осуществляется как и во втором способе по ALT+Tab. И выход из игры и вход осуществляются почти мгновенно.

v Переименовываем файл скрипта.

Если по какой либо причине вы не желаете для этого воспользоваться, встроенной в редактор функцией копирования, то не достаточно просто изменить имя при помощи «проводника». Делать это придется при помощи XML-редактора. В нашем примере нам требуется переименовать файл скрипта с именем «a.check.script» в «main.script». Заходим в папку \script и открываем его при помощи XML-редактора ( в моем случае это, FrontPage), находим в нем строку:

<name>a.check.script</name> и

<sval type="string" val="a.check.script" />

изменяем в них a.check.script на main.script и сохраняем под именем main.script. Теперь в папке скрипт лежит новый файл с именем main.script, являющийся копией нашего исходного скрипта a.check.script.

v Обходим ограничение редактора ScE на использование русской раскладки.

У нас возникла ситуация когда нам необходимо послать русско-язычное сообщение, но мы не хотим использовать языковой файл. Справиться с ситуацией нам поможет тот же XML-редактор.

В нашем скрипте из редактора ScE создаем переменную которая должна содержать русско-язычный текст, но вместо текста вводим, например «XXXXX», теперь сохраняем скрипт, и выходим в виндовс. Открываем файл скрипта в XML-редакторе и находим строку:

<line linenr="001" indent=""><var>$qqq&#160;=&#160;</var><var>'XXXXX'</var></line>

(linenr="001" – указывает на номер строки в скрипте)

и в последней очень длинной строчке находим:

<sval type="string" val="XXXXX" />

заменяем в обоих строках «ХХХХХ» на на русско-язычный текст, не нарушая целостности самой структуры файла (текст может быть длиннее чем пять символов, как в нашем примере). Сохраняем. Перезагружаем игру или загружаем сохраненку. Открываем в редакторе игры наш скрипт и видим что текст переменной изменен. Но помните, что редактор ScE не позволяет редактировать текст переменных, а только его заменяет его. Поэтому если вы ввели что либо не правильно, то изменять придется, снова используя XML-редактор.

И еще одно предупреждение, не следует изменять текст содержащий спецсимволы, если вы ошибетесь то игра перестанет загружаться, до тех пор пока вы не удалите испорченный файл скрипта из папки \script.


Структура НС

При просмотре НС в браузере IE, хорошо видна вся структура скрипта. Давайте рассмотрим ее подробней. Возьмем для примера внутренний скрипт !ship.cmd.follow.pl:

Script !ship.cmd.follow.pl

Version: 1
for Script Engine Version: 20

Description

Ship Player COMMAND FOLLOW

Arguments

  • 1: target , Var/Ship , 'the target'

Source Text

 001 @ = [THIS] -> call script '!ship.cmd.follow.std'  :       the target=$target     follow distance=null
 002   return null

 signde

Данный скрипт связан с командой для корабля принадлежащего игроку «Следовать за кораблем». Скрипт сам по себе очень маленький, передающий управление в более сложный скрипт. Но для рассмотрения структуры скрипта нам его будет достаточно.

v Имя скрипта (Script)

Первое что мы видим это имя скрипта. В Х2 имя скрипта имеет большое значение, т.к. в имени скрипта содержится много важной информации обрабатываемой ScE. В нашем примере имя начинается со знака «!» это сообщает редактору о том, что данный скрипт является системным и не подлежит редактированию. Скрипты со знаком «!» не будут отражаться в списке доступных для редактирования скриптов в редакторе. В Х2 присутствуют следующие типы имен: “init.* ”, ”setup.* ”, “al.plugin.* ”, “galaxy.* “. Каждое из имен имеет определенное значение, и скрипты с такими именами выполняются игрой автоматически.

o       Init Scripts: скрипты с именами “init.* ” и “!init.* “ являются скриптами инициализации, то есть они загружаются автоматически каждый раз когда вы запускаете игру или загружаете сейв. Но обратите внимание на то, что загрузка скриптов init происходит до инициализации галактики (то есть до создания кораблей и станций). Поэтому нужно быть осторожным используя данный тип имен для скриптов работающих с объектами в галактике.

o       Setup Scripts: скрипты с именами “setup.* ” и “!setup.* “ запускаются автоматически при создании новой игры или загрузке сейва. Загрузка скриптов setup происходит после инициализации галактики (то есть все объекты уже созданы). Использование setup для скриптов активно работающих с объектами в галактике, позволяет избежать многих ошибок которые могут возникнуть при использовании init.

o       AL Plugin Scripts: скрипты с именами “al.plugin.* ” и “!al.plugin.* “ отвечают за искусственную жизнь в галактике (патрули секторов, транспорты летающие между станциями, в том числе и залетающие на станции игрока) каждый скрипт данного типа отвечает за какой ни будь конкретный процесс происходящий в галактике связанный с искусственной жизнью.

o       Galaxy Ship Init Scripts: скрипты с именами “galaxy.* “ используются для запуска иных чем встроенная в Х2 карта. Скрипты "galaxy.* “ создает стартовый корабль игрока и помещает в нужную точку на новой карте. ScE при запуске проверяет наличие скрипта с именем “galaxy.<имя карты> “ или “!galaxy.<имя карты>“ Чтобы при старте новой игры на новой карте, оказаться в заданном секторе карты и на заданном корабле с определенным количеством оборудования в трюме и нужным кол-вом денег на счете, нужно создать скрипт с именем galaxy.имя_файла_карты.initplayership следующей структуры:

§ выбрать сектор с нужными координатами

§ plship-> создать в этом секторе корабль, принадлежащий пилоту

§ добавить в трюм необходимые апгрейды

§ return plship

Имя файла карты в имени скрипта указывается без расширения .xml

Обратите внимание на одну особенность при использовании имен скриптов init, setup, !init, !setup. Скрипты !init и !setup запускаются всегда при старте или загрузке сэйва. Если использовать скрипты такого типа, НЕ подписанные Егософтом (цифровая подпись скрипта, см. ниже), то игра автоматом приобретает статус Modified. Скрипты типа init и setup запускаются ТОЛЬКО в игре со статусом Modified, в не модифицированной игре они не будут запускаться, несмотря на то, что находятся в папке \scripts.

v Версия (Version)

В исходном тексте каждого скрипта содержится информация о версии данного скрипта. Значение этого параметра задается автором, а сделано это для того, чтобы автор мог указать версию в случае если скрипт был модифицирован. Версия скрипта отражается в окне «Редактор скриптов», в листинге скриптов доступных для редактирования, следующий столбец за именем скрипта.

В следующей строке отражается версия ScE (Script engine version), а это делается для того чтобы определить будет ли данный НС скрипт работать под управлением установленной и вас игры. Начиная с версии 1.4 версия ScE выше 25 (включительно). Совместимость скриптов обеспечивается по принципу возрастания, то есть более новая версия ScE поддерживает скрипты написанные в более старой.

v Описание (description)

В этой строке содержится краткое описание скрипта. Создается автором данного скрипта. Описание скрипта отражается в окне «Редактор скриптов», сразу за версией скрипта. В нашем случае «Команда следовать, используемая для корабля игрока».

v Аргументы (Arguments)

Аргументы это входные данные, от которых зависит результат выполнения скрипта (куда полетит корабль или какой товар покупать и т.п.). Аргумент в ScE Х2 состоит из трех частей:

o       Name: имя аргумента, должно состоять из символов любого регистра (строчные, прописные), цифр. ScE создаст переменную имя которой будет соответствовать имени аргумента, с этой переменной скрипт сможет работать как с обычной переменной.

o       Type: тип данных переменной-аргумента. Информация для ScE о том какой тип данных содержит аргумент.

o       Description: описание. Задается краткое описание аргумента. Описание отражается в нижней части экрана, когда редактор запрашивает значение аргумента при запуске скрипта, что очень удобно для других пилотов использующих ваш скрипт. Так же Description будет отражаться при использовании команды call script, необходимые аргументы для вызова скрипта будут отображены как Description аргументов вызываемого скрипта. В нашем примере в строке 001 вызывается скрипт “!ship.cmd.follow.std” далее идет “the target” и “follow distance”, это говорит о том что в вызываемом командой call script скрипте “!ship.cmd.follow.std” имеются два аргумента, необходимых для выполнения скрипта, у которых в описании первого записано “the target”, а второго “follow distance”

v Исходный текст (Source text)

Исходный текст скрипта, от есть само тело скрипта. Состоит из последовательности команд, инструкций, операторов и наборов значений и переменных. Все это интерпретируется и выполняется ScE.

v Цифровая подпись навигационного скрипта

Вы наверное обратили внимание на то, что ниже команды RETURN NULL находится строчка содержащая одно слово «signed». Наличие этой строчки в скрипте, говорит о том, что данный скрипт имеет цифровую подпись от Egosoft. Это означает, что данный скрипт прошел некую сертификацию и официально допущен к использованию в не модифицированном режиме игры.

Скрипт написанный любым пилотом может быть подписан Egosoft’ом, для этого он должен соответствовать определенным условиям. Занимаются вопросами подписи скриптов два пилота BurnIt и mkess, именно они будут принимать решение подписывать или не подписывать ваш скрипт. Для рассмотрения вашего скрипта, он должен быть выслан на адрес scripts@egosoft.com. Также, на подпись можно отправить скрипт автором которого вы не являетесь, после рассмотрения, если скрипт будет принят, то Egosoft свяжется с автором и в случае его согласия скрипт будет подписан.

Основные требования предъявляемые к скриптам:

· Скрипт не должен полностью автоматизировать работу экономики (то есть осуществлять полностью автоматическое управление всеми фабриками игрока). Хотя есть оговорка о том, что в принципе какой скрипт может быть подписан, в случае если например: игрок уже является владельцем не одного десятка фабрик и его торговый рейтинг не меньше чем Промышленник, то он может приобрести какое ни будь новое оборудование добавляемое этим скриптом за баснословные деньги.

· Приветствуются скрипты расширяющие работу стандартных команд.

o       Скрипты расширяющие структуру меню

o       Микроменджмент (перевод денег на счет игрока, предупреждение о нехватке денег или ресурсов, и т.п.)

o       Улучшающие стандартные боевые, добывающие, собирающие и т.п. скрипты

o       Патрули секторов, галактик осуществляющих защиту собственности.

o       Скрипты улучшающие AL.

o       Улучшающие торговые и транспортные скрипты.

· Скрипты не должны без необходимости обращаться к системным скриптам. Например использовать системный скрипт !Move.movetostation для определения прибыл ли объект к точке следования, вместо команд "if THIS-> landed" или "If DOCKEDAT == $targetstation".

Если Egosoft находит мелкие недостатки в скрипте, то автору предлагается устранить их. И после устранения этих недостатков, скрипт получит долгожданную «signed».


Просмотр и редактирование НС

Все скрипты используемые в Х2 располагаются в папке \scripts, расположенной в установочной папке игры (по умолчанию установка производится в каталог "C:\Program Files\Еgosoft\X2 - The threat").

В изначально установленной игре, в папке \scripts находится два вида файлов *.PCK и *.XML. PCK – это файлы упакованные, как работать с этими файлами рассмотрим далее в этом разделе. XML – это распакованные файлы скрипов за исключением одного файла с именем x2script.XSL это внутренний файл описатель, содержащий информацию необходимую для просмотра XML кода в браузерах типа Internet Explorer.

v Просмотр скриптов из папки /scripts

Для просмотра распакованных XML файлов (НС игры Х2), нужно открыть папку /scripts и кликнуть на любом из файлов с расширением XML (на компьютере должен быть браузер Internet Explorer). В открывшемся окне браузера отразиться исходный текст НС.

v Просмотр упакованных скриптов (PCK)

Изначально, скрипты поставляемые в дистрибутиве игры находятся в запакованном состоянии и имеют расширение PCK. Для просмотра этих скриптов нужно произвести их распаковку. Официальная программа распаковки называется x2tool.exe, эта программа позволяет упаковывать и распаковывать PCK файлы. Данная программа не поставляется в комплекте с игрой, взять ее можно на сайте официальном сайте Egosoft (www.egosoft.com).

Синтаксис x2tool.exe для распаковки:

x2tool -unpack <имя файла>.pck <имя файла>.xml

Но имеется и другая альтернатива, это программа unPaCKer.exe написанная пилотом Алексейко Дмитрием aka Dimaxx, данная программа имеет русскоязычный интерфейс и проста в использовании. Понять как она работает не составит труда. Найти ее можно на сайте ЕГ (http://www.elite-games.ru/_egm_scripts/url.php?action=gotourl&url=/downloads/x2/unpacker.exe)

После распаковки PCK файлов, если вы не выбирали в установках программы unPaCKer.exе удалить или переименовать исходные файлы, то следует либо удалить их либо переместить в какую ни будь другую папку. А все появившиеся файлы с расширением XML теперь доступны для просмотра через Internet Explorer.

v Просмотр сторонних скриптов

Сейчас в Интернете можно найти огромное количество скриптов для Х2 написанных пилотами. Если у вас имеется какой то скрипт написанный другим пилотом, то для того чтобы посмотреть его, необходимо в папку где находятся файлы скрипта скопировать файл описатель x2script.XSL из папки /scripts и кликнуть на файле скрипта исходный текст которого вы хотите посмотреть .

v Редактирование скриптов

Редактирование НС возможно только во встроенном в игру редакторе. Для редактирования доступны только те скрипты, файлы которых находятся в папке /scripts. Имя файла не должно начинаться с символа «!», иначе браузер скриптового редактора не увидит этот скрипт (см. структура скрипта).


Вступление

v Что такое – навигационный скрипт?

Вы никогда не задумывались над тем, что происходит в электронном мозгу корабля после того, как вы отдаете ему команду «Вернуться на базу»? Нет ? Так давайте попробуем в этом разобраться.

И так, предположим мы находимся в секторе «Фортуна Елены», а базой приписки нашего корабля является «Ранчо аргну» в секторе «Стена». Из консоли нашего корабля отдаем приказ: «Вернуться на базу». И наблюдаем за происходящим – наш кораблик ложится на курс к западным вратам, набирает скорость и спустя несколько минут мы проходим врата и оказываемся в секторе «Президентский рубеж». Теперь наш путь лежит к северным вратам. Но вот и они позади. Мы долетели до сектора «Стена» войдя в него через южные врата. Именно в этом секторе находится наше «Ранчо аргну». Наш корабль ложится на курс сближения с базой, и движется к ней. Стыковка. Все просто. А теперь представьте, что делали бы вы, если пришлось вести корабль на базу в ручную.

Давайте составим последовательность наших действий:

  1. Смотрим к какой базе приписан корабль.
  2. Заглядываем в карту галактики и определяем где находится наш корабль. В нашем случае это сектор «Фортуна Елены»
  3. Находим сектор «Стена».
  4. Составляем маршрут. И так, из сектора «Фортуна Елены» через западные врата в сектор «Президентский рубеж», дальше через северные врата в сектор «Стена»
  5. Отправляемся в путь.
  6. Вот мы и в секторе «Стена». Открываем карту сектора находим нашу базу, выбираем ее целью и летим к ней.
  7. Вот уже расстояние до станции меньше 5 км. Включаем связь и запрашиваем разрешения на посадку. Ответ утвердительный, стыкуемся.

И так, перед нами список наших действий, этакий сценарий полета к базе. Если мы сравним последовательность наших действий с действиями автопилота, то на лицо тот факт, что мы выполняли практически одинаковую последовательность действий. Получается автопилот действовал по такому же сценарию ? И это совершенно верно, ведь дословный перевод с английского слова script означает «сценарий». Так что запустив в командной консоли нашего корабля команду «Вернуться на базу», мы на самом деле запустили навигационный скрипт (далее НС) выполняющий полет на базу. А проанализировав последовательность своих действий, мы составили нечто иное как схему НС. Для того, чтобы нам полностью понять что же такое скрипт разберемся еще с несколькими понятиями:

¨ Script engine (интерпретатор скриптовых команд), далее в тексте ScE – интерпретатор это сам центр обработки команд, производящий анализ и интерпретацию команд находящихся в теле скрипта и обеспечивающий их исполнение.

¨ Инструкции, функции, операторы – составляющие самого языка скриптописания. Это понятные ScE наборы операторов из которых собственно и состоит скрипт. Подробное изучение нам предстоит далее.

¨ Сегмент – какой либо определенный кусок кода НС.

¨ Процедура – сегмент выполняющий одно какое либо действие. Например процедура проверки наличия денег на счету станции.

¨ Аргумент - входные данные, задаваемые для НС. Именно от аргументов зависит результат выдаваемый скриптом.

¨ Примитив – небольшой скрипт выполняющий как правило одну какую нибудь функцию и возвращающий значение в вызывающий скрипт. Это маленький кирпичик в огромном здании сложного скрипта. Цель примитивов это освобождение тела большого скрипта от часто повторяющихся кусков кода выполняющих одну и туже функцию (например, если в скрипте по мере его выполнения многократно производится сканирование галактики, то во избежание многократного переписывания процедуры сканирования, создается примитив который можно вызвать из основного скрипта и он просканировав галактику вернет основному скрипту результат поиска.

И так теперь мы имеем поверхностное представление о том, что такое – навигационный скрипт. Давайте сформулируем понятие НС.

Навигационный скрипт – это сценарий последовательности действий и реакций объекта на внешние изменения, записанный при помощи команд и инструкций интерпретируемых и исполняемых ScE Х2.

v Запасемся инструментом.

Для того чтобы приступить к изучению скриптописания, следует запостись некоторым набором инструментов, которые значительно облегчат вам эту задачу.

Вам понадобиться:

  1. Windows Notepad (Блокнот), универсальное средство на все случаи жизни.
  2. XML-редактор, любой корректно работающий (лично я использую FrontPage 2003), но ограничений здесь нет. Любой которым вы умеете пользоваться.
  3. Internet Explorer, при помощи этого браузера удобно просматривать листинги скрипта.
  4. Тек же понадобиться набор специфических программ для распаковки и прочих действий производимых над файлами Х2. Все они описаны в тексте данного учебника, там же указанны ссылки на них. Почти все, что вам может понадобиться имеется на сайте Elite Games.

Это собственно и все, что вам может пригодиться при работе с навигационными скриптами Х2.

v Синтаксис команд HC.

В угловые скобки заключены значения не являющиеся постоянными, это значения задаваемые для инструкции пользователем или возвращаемые значения (использование угловых скобок условно, только для описания, в самом скрипте они не используются), текст без скобок является самой инструкцией.

<RetVar/IF> <object>buy <Var/Number> units of <ware>

В данном примере <RetVar/IF> говорит о том, что возвращаемое командой значение может быть присвоено переменной <RetVar>, либо являться аргументом для таких операторов IF, IF NOT, SKIP, SKIP NOT, WIHLE, WHILE NOT. <object> указывает в отношении какого объекта выполняется команда. В данном примере объектом должен быть корабль, а вообще объектом может быть станция, корабль, астероид, планета, туманность и т.п. <Var/Number> сообщает о том, что для команды необходимо указать переменную число, либо ввести число непосредственно в редакторе. <ware> является указателем на какой либо товар, а товаром в "X2 The Threat" может являться все, что можно продать или купить (так же в Х2 имеются <sector> <station> <ship> и т.п. в редакторе все возможные переменные отображаются в виде списка, в некоторых версиях они переведены на русский язык <Перем/Станция>. Например версия НД)

Пример:

…

022 $amount = 100

023 $ware = Батареи

024 $obj = [THIS]

025 IF NOT $obj buy $amount units of $ware

…

Так же, в синтаксисе команд вы можете встретить:

<Value> - значение неопределенного типа. Тут надо смотреть по смыслу, что подставлять. В тексте также будут применяться

<Object Command> - команда объекту. Это константа, выбирается из списка возможных.

<Object Signal> - сигнал объекту. Это тоже константа.

<Flag> - константа флаг.

[TRUE]|[FALSE] – аргументом должна являться константа TRUE или FALSE

v В каком редакторе пишется НС, и где его взять ?

На сегодняшний день написать НС можно только во встроенном в "X2 The Threat" редакторе, это немного не удобно но пока альтернативы нет. Ввод команд в редакторе осуществляется выбором в меню нужной команды, так же вводятся переменные и другие необходимые данные. С клавиатуры вводятся только числовые и текстовые значения, хотя вход в интерфейс для ввода осуществляется также через выбор соответствующего пункта в меню.

Изначально редактор находится в деактивированном состоянии и для его использования нужно провести активацию. Делается это следующим образом:

  1. На корабле вылетаем в космос.
  2. Набираем на клавиатуре следующее слово, важно с большой буквы без кавычек, «Thereshallbewings»
  3. Раздается краткий звуковой сигнал. Редактор активирован.

После того как раздался звуковой сигнал в левом верхнем углу должна появиться полупрозрачная надпись «Modified» (это происходит не во всех версиях игры, в версии от НД этого не происходит). Значок сообщает о том что игра модифицирована. Сделано это в связи с тем, что при помощи НС можно сделать многие вещи, такие как добавить на счет игрока несколько миллионов кредитов (то есть, чистое читерство), а так как значок будет сохранятся после активации редактора во всех сейвах, то это должно сообщить другим игрокам честным ли образом что либо в игре было достигнуто.

Теперь нажимаем Shift-C и оказываемся в командном меню, ищем появившуюся строчку «Редактор скриптов» или нажимаем «S».

v Какие бывают скрипты?

В ScE "X2 The Threat" присутствует два типа скриптов, это Глобальные скрипты и Локальные скрипты.

Глобальный скрипт – к глобальным скриптам относятся НС исполняемые без привязки к какому либо объекту (например, скрипты инициализирующие командное меню).

Локальный скрипт – это скрипт запускаемый непосредственно для какого-либо объекта, и существующий только пока существует сам объект.


Введение в скриптописание

Введение в скриптописание Х2

v Переменные. Типы переменных

Использование переменных является простым способом хранения временных данных в вашем НС и передачи их в нужном виде ScE Х2. Переменные могут являться указателями на объект, хранить в себе данные его типе ($station = [HOMEBASE]), а также результаты математических, логических или операций сравнения ($res = 2+2), принимать значения ЛОЖЬ или ИСТИНА ($res= [FALSE]), содержать текст ($text=Hello world !!!). Имя переменной задается пользователем и отображается после знака $<имя> . Имя должно состоять из одного слова, может содержать цифры, строчные и прописные буквы латинского алфавита (но начинаться должно с буквы). При создании переменной желательно давать ей максимально информативное имя, т.к. в сложных скриптах используется не один десяток переменных и чтобы избежать путаницы имена должны быть понятны и сообщать о содержимом переменной. Например, переменная содержащая информацию о свободном месте в трюме корабля может иметь имя $ShipFreeAmount. Такое имя сообщает пользователю о том какие данные содержит переменная.

В ScE присутствуют следующие типы переменных:

Приватные переменные – переменные относящиеся непосредственно к скрипту в котором они созданы. Над этим типом переменных можно производить любые операции, математические, логические, сравнения. Приватные переменные недоступны другим скриптам. Формат записи $<имя>.

…

002 $test = 5

003 $total = $test+10

004 if $total < 10

…

Локальные переменные – переменные этого типа относятся к определенному объекту, но доступны другим скриптам. Все операции с локальными переменными осуществляются по принципу Считал-Изменил-Записал. Для выполнения каких либо действий над локальной переменной, нужно получить ее значение при помощи команды get local variable в приватную переменную. Произвести над приватной переменной нужные операции и командой set local variable записать полученный результат обратно в локальную переменную.

...

005 $test = [THIS] get local variable: name= localVar

006 $test = $test + 1

007 [THIS] set local variable: name= localVar value=$test

…

Глобальные переменные – этот тип переменных не привязан ни к одному объекту, это делает их доступными для любого скрипта просто по имени этой переменной. В связи с этим, объявляя глобальную переменную следует позаботиться о том, чтобы ее имя было оригинальным и информативным. Принцип выполнения операций на глобальными переменными тот же, что и у локальных. Команды для работы с глобальными переменными get global variable и set global variable.

…

008 $test = get global variable: name=globVar

009 $test = $test + 1

010 set global variable: name=globVar value=$test

…

Теперь мы разобрались какие бывают типы переменных и для чего они нужны. Осталось разобраться как они устроены.

В ScE любая переменная состоит из двух частей. Первая, это тип данных. Вторая часть сами данные. Тип данных сообщает ScE как работать с содержащимися в переменной данными. Сделано это для того, что бы работая с переменными мы могли не задумываясь помещать в них как информацию о какой либо точке в пространстве сектора, так и просто какое ни будь числовое значение не выполняя никаких дополнительных манипуляций, кроме как указать тип данных который будет хранится в создаваемой переменной. Всего в ScE "X2 The Threat" имеется 22 типа данных:

DATATYP_NULL | Переменная имеет нулевую величину
DATATYP_UNKNOWN | Это тип данных устанавливается ScE если он не может определить тип данных переменной.
DATATYP_VAR | Этот тип является внутренним типом переменной ScE. Этот тип является внутренним типом переменной и значение задается непосредственно ScE
DATATYP_CONST | Переменная-константа описанная в ScE. Этот тип является внутренним типом переменной и значение задается непосредственно ScE
DATATYP_INT | Численная переменная в диапазоне [-2147483648,2147483647] или [-0x80000000,0x7FFFFFFF]
DATATYP_STRING | Переменная содержащая данные в виде текста. Пример: $str= Hello World!!!
DATATYP_SHIP | Указатель на корабль. Переменная ссылается на объект Корабль
DATATYP_STATION | Указатель на станцию. Переменная ссылается на объект Станция
DATATYP_SECTOR | Указатель на сектор. Переменная ссылается на объект Сектор
DATATYP_WARE | Переменная Товар в "X2 The Threat" это, все что можно купить или продать (кроме кораблей станций)
DATATYP_RACE | Переменная-указатель на расу объекта (Аргон, Борон, Сплит, Игрок и т.д.).
DATATYP_STATIONSERIAL | Порядковый номере объекта Станции и соответствующая ему буква в греческом алфавите. (альфа, бета, гама, и т.д.)
DATATYP_OBJCLASS |
DATATYP_TRANSPORTCLASS | Переменная константа принимающая значение класса транспорта (ST, XL, L, etc.)
DATATYP_RELATION | Отношение Друг (Friendly)– Нейтральный (Neutral)– Враг (Enemy)
DATATYP_OP | Тип данных Оператор. Этот тип является внутренним типом переменной и используется непосредственно самим ScE
DATATYP_EXPR | Выражение. Этот тип является внутренним типом переменной и используется непосредственно самим ScE
DATATYP_OBJECT | Указатель на объект. Переменная ссылается на объект не являющийся кораблем, станцией или сектором, а только солнцем, туманностью или астероидом.
DATATYP_OBJCOMMAND | Переменная содержит мнемосхему команды
DATATYP_FLRET | Переменная содержит код возврата команды fly to (описание далее)
DATATYP_DATATYP | Переменная содержит тип данных. Используется в инструкциях типа get datatype
DATATYP_ARRAY | Переменная является массивом

Большинство используемых НС инструкций возвращают результат который может быть помещен в переменную для дальнейших действий. А непосредственно над переменной, вы сможете выполнять арифметические, логические и т.п. операции как было описано в начале главы.

Для объявления переменной используется инструкция из раздела «Основные команды» “<RetVar/IF><Expression>”. Выбрав данную инструкцию в списке редактор предложит ввести имя переменной. После ввода нажимайте «Enter». Редактор вернется к листингу скрипта и вы увидите следующие выражение:

001 $MainVar = «?»

«?» красным цветом, говорит о том что редактор ожидает дальнейшего ввода данных. Нажимайте «Enter» выберете тип данных из открывшегося списка, а затем и сами данные. Например: выбираем тип данных станция, далее редактор предлагает выбрать сектор и станцию при помощи открывающихся интерфейсов. Выбираем сектор Аргон Прайм станцию Арогонская торговая станция.

001 $MainVar = Аргонская торговая станция [Аргон Прайм]

Теперь объявленная нами переменная $MainVar указывает на Аргонскую торговую станцию находящуюся в секторе Аргон Прайм.

v Массивы.

Продолжая рассматривать наш пример предположим, что у нас возникает потребность в том, чтобы наша переменная содержала в себе указатель не на одну станцию, а на целый список. Мы могли бы это решить объявив для каждой станции из списка свою собственную переменную, но если в нашем списке несколько десятков или даже сотен станций, то время и силы потраченные на эту работу начисто отбили бы интерес к скриптописанию. Здесь на помощь нам приходит особая переменная, которая умеет хранить в себе огромное количество однотипных данных, название этой переменной МАССИВ. В массиве данные расположены как в таблице с пронумерованными строками. Номера строк называются индексом массива, общее количество строк размером массива, а данные элементами массива. То есть, для того чтобы использовать данные из массива нам необходимо установить указатель индекса на нужный элемент и получить его значение в переменную. Синтаксис такой операции с массивом в ScE выглядит так:

…

006 $MainVar = $array [2]

…

В данном примере элемент массива $array с индексом [2] будет помещен в переменную $MainVar.

Следует обратить внимание на то, что индексация массивов начинается с 0, а не с 1. То есть, в массиве размерностью в десять элементов, первый элемент будет иметь индекс 0, а последний 9.

Теперь давайте рассмотрим как в ScE организован сам массив.

Прежде всего запомните, что переменная типа <Var/Array> в ScE Х2 сама по себе не является массивом, а только указателем на область памяти где он храниться. То есть когда вы используете инструкцию <RetVar>=array alloc: size=<Var/Number> для того чтобы создать новый массив, вы даете ScE указание распределить память под указанное в инструкции количество элементов и вернуть в переменную указатель на эту область. Этот указатель называется – пойнтер. Именно из-за этого, в ScE для выполнения копирования массивов предусмотрены специальные инструкции, т.к. скопировать массив в другую переменную при помощи инструкции $array2=$array1 на удастся. После того как ScE выполнит эту команду, мы будем иметь две переменные указывающие на один и тот же массив.

соответственно если произвести работу с каким либо элементом массива $array1, значения изменяться и для псевдо массива $array2:

…

005 $array2=$array1

006 $array1 [2] = 5

007 $var = $array2 [2]

…

значение переменной $var = 5, так как пойнтеры $array1 и $array2 указывают на одну и ту же область памяти.

Для того, чтобы получить копию массива, нам следует использовать команду <RetVar>=clone array <Var/Array>: index <Var/Number> <Var/Number>. Если в нашем примере заменить строку 005 на :

005 $array2=clone array $array1: index 0 … 2

Теперь мы имеем два независимых массива, а переменная $array2 содержит пойнтер на новую область памяти в которой расположена копия трех элементов из массива $array1.

Не забывайте учитывать данную особенность работы ScE с массивами при написании своих скриптов.

При создании массива, также надо учитывать тип данных хранящийся в нем. Например если массив содержит данные о точке в секторе Var/Sector Position, то данные будут располагаться следующим образом: координата x[0], y[1], z[2], sector[3]. Соответственно если в массиве информация о трех точках, то размерность массива составит 12 элементов с 0 по 11, первая точка индексы [0-3], вторая [4-7], третья [8-11].

v Константы

Константы – это величины имеющие постоянное значение. В ScE Х2 используется несколько типов констант: первый тип Глобальные константы, это константы которые может использовать практически любая команда, и приватные константы, это константы зарезервированные для каких либо команд и используются только ими.

В таблице указанны все используемые константы имеющиеся в Х2:

Глобальные константы

THIS | указатель на объект, который только что получил команду и занялся ее выполнением. Например, вы запустили на корабле команду "Покупать товар". Этот корабль и будет THIS.
PLAYERSHIP | Указывает на корабль в котором сидит игрок
HOMEBASE | Указывает на базу приписки текущего объекта
ENVIRONMENT | возвращает объект-окружение для другого объекта. Например, если корабль в космосе, то его окружение объект "сектор", а если пристыкован к базе - "база" и т.п.
SECTOR | возвращает объект-сектор, в котором находится текущий объект.
OWNER | Константа указатель на владельца текущего объекта
NEAREST | Константа указывающая на ближайший объект, по отношению к текущему объекту.
FALSE | Константа ЛОЖЬ
TRUE | Константа ИСТИНА
DOCKEDAT | Константа указывает на станцию или носитель в доке которого находится текущий корабль. Если корабль не в доке, то принимает значение FALSE

Приватные константы:

Formation.Delta | Константы указывающие на тип построения для команды set formation подробно рассмотрены в описании команды.
Formation.Line
Formation.X
Formation.XDelta
Formation.BigShipEscort
Formation.Pyramid
Formation.Random
Find.Random | Константы Find являются флагами при организации поиска, каждая константа имеет числовое значение, допускается использовать эти константы в виде комбинаций составленных через побитовое ИЛИ «|».
Find.Nearest
Find.ExactJumps
Find.Enemy
Find.Neutral
Find.Friend
Find.Multiple
Find.TypeAsWareCategorie
Find.IllegalWare
Find.ForceUsePos
CmdConCheck.Available | Константы используемые командой set script command upgrade … script, как флаги возвращаемые проверочным скриптом. Флаги используются для активации или деактивации строки в командном меню. (См. описание команды)
CmdConCheck.Disabled
CmdConCheck.OneTime
CmdConCheck.Infinite
CmdConCheck.NeedHomeStation
CmdConCheck.NeedHomeBase
IncomingTransmission.SOS | Набор констант для аудиокоманды play sample: incoming transmission, (подробное описание этих констант в описании команды)
IncomingTransmission.Message
IncomingTransmission.Greeting
IncomingTransmission.Scanned
Comm.DLG_C_START_FIGHTING | Используется аудиокомандой send audio message, (см. описание команды)
Comm.DLG_POL_ILLEGAL_GOODS
Comm.DLG_POL_LAST_WARNING
Comm.DLG_POL_LEGAL_GOODS

Если вы просматривали список констант который предлагает редактор, то наверняка заметили, что в этот список не вошли несколько групп констант. Это специальные внутренние константы ScE (SSTYPE, ACTION, GalaxyFlight) и нам для использования они недоступны (то есть выбрать мы их можем, но они не имеют никакого информативного содержания).

v Операции

Под операцией подразумевается, нахождение некоторой величины полученной в результате выполнения некой последовательности действий, производимых над одной или несколькими величинами. Величины, представляющие из себя сами объекты операций, называются операндами.

В ScE Х2 операндами могут являться константы, числа, переменные, строковое выражение, указатели на объект. Какие именно действия нужно произвести над операндами, ScE сообщает знак операции (+,-,*,/ и т.п.).

Все операции производимые в ScE, можно разделить на несколько групп:

· Арифметические;

· Сравнения;

· Логические

· Побитовые (формальная логика)

· Отрицания и дополнения

Давайте подробнее рассмотрим каждую группу:

Арифметические операции.

Арифметические операции выполняют общий набор математических действий (сложение, вычитание, умножение, деление и т.п.). Обратите внимание, что в ScE все операции цельно-численные, то есть не допускается использования дробных чисел, все числовые операнды должны являться целыми числами. Последовательность выполнения вычислений математическая, то есть слева на право, умножение имеет более высокий приоритет чем сложение. В выражениях можно изменять последовательность вычислений используя скобки (угловые скобки), допускается многоуровневое построение выражений используя вложенность скобок, например математическое выражение ((3+2)*5)+10, в ScE будет выглядеть так: [[3+2]*5]+10.

+ | сложение
- | вычитание
* | умножение
/ | Деление
mod | Получение остатка от деления
[ | Математические скобки
]

Сложение:

001 $MainVal = 3 *Присвоить переменной $MainVal значение 3

002 $Total = $MainVal + 8 *Прибавить к $MainVal число 8, $Total = 11

003 $Total = $Total - $MainVal *Операция вычитания $Total = 8

004 $Total = 5 * 6 *Умножение $Total = 30

005 $Total = [2+3]*5 *Использование скобок $Total = 25

006 $Total = 7+[-2] *Использование отрицательных чисел $Total = 5

007 $Total = 49 / 10 *Деление $Total = 4 (результат цельно-численный)

008 $Total = 49 / [-10] *$Total = -4

009 $Total = 49 mod 10 *Остаток от деления $Total = 9 (10*4=40+9=49)

010 $Total = 49 mod [-10] *$Total = 9

011 $Total = -49 mod [-10] *$Total = -9

Диапазон используемых чисел ограничен от -2 147 483 648 до 2 147 483 647 или в шестнадцатеричном исчислении от -0x80000000 до 0x7FFFFFFF.

Следует заметить о еще одной особенности оператора «+», это возможность работать со строковыми переменными. При помощи этого знака можно сложить две переменные содержащие текстовые строки.

Пример:

001 $str1 = ‘Наша Маша’

002 $str2 = ‘ громко плачет.’

003 $str1 = $str1 + $str2

Теперь переменная, $str1 содержит строку «Наша Маша громко плачет.» Для того, чтобы соединяемые фразы были разделены пробелом, не забывайте добавлять его в конце первой или начале второй.

Операции сравнения.

Операции сравнения, формируют значение [FALSE] (0 Ложь) или [TRUE] (1 Истина) в зависимости от результата обработки операндов. Возвращаемое операцией значение используется для обработки такими операторами как IF, IF NOT, SKIP IF. SKIP IF NOT, WHILE и т.п. Операции сравнения выполняются слева на право.

== | проверка условия «равно»
!= | проверка условия «не равно»
> | проверка условия «больше»
< | проверка условия «меньше»
>= | проверка условия «больше или равно»
<= | проверка условия «меньше или равно»

Примеры использования:

001 $variable = 10 *присвоить переменной $variable значение 10

002 if $variable == 10 *сравнить равно ли значение $variable, 10 [TRUE]

003 skip $variable > 5 *сравнить $variable больше 5 [TRUE]

004 skip not $variable < 5 *сравнить $variable меньше 5 [FALSE]

005 while $variable >= 20 *сравнить $variable больше или равно 20 [FALSE]

006 while not $variable != 20 *сравнить значение $variable не равно 20 [TRUE]

Логические операции.

К логическим операциям относиться операция логического «И» (оператор AND) и логического «ИЛИ» (оператор OR). Логические операции не вызывают ни каких арифметических преобразований. Они оценивают каждый операнд с точки зрения его эквивалентности нулю. Результатом логической операции является [FALSE] (0 Ложь) или [TRUE] (1 Истина). Операции выполняются слева на право.

Операция логического И (оператор AND) вырабатывает значение 1, если оба операнда имеют значение 1. Если один из операндов равен 0, то результат будет равен 0.

Примеры:

001 $variable = 10

002 if $variable == 10 AND 5+5==10 *результат 1 [TRUE]

003 if $variable == 10 AND 5+5==11 *результат 0 [FALSE]

Операция логического ИЛИ (оператор OR) выполняет над операндами операцию включающего ИЛИ. Она вырабатывает значение 0, если оба операнда имеют значение 0, если какой-либо из операндов имеет ненулевое значение, то результат операции равен 1.

Примеры:

001 $variable = 10

002 if $variable == 10 OR 5+5==10 *результат 1 [TRUE]

003 if $variable == 10 OR 5+5==11 *результат 1 [TRUE]

004 if $variable == 11 OR 5+5==11 *результат 0 [FALSE]

Побитовые операции (формальная логика).

К поразрядным операциям относятся: операция поразрядного логического "И" (&), операция поразрядного логического "ИЛИ" ( | ), операция поразрядного "исключающего ИЛИ" (^).

Операция поразрядного логического И (&) сравнивает каждый бит первого операнда с соответствующим битом второго операнда. Если оба сравниваемых бита единицы, то соответствующий бит результата устанавливается в 1, в противном случае в 0.

Операция поразрядного логического ИЛИ (|) сравнивает каждый бит первого операнда с соответствующим битом второго операнда. Если любой (или оба) из сравниваемых битов равен 1, то соответствующий бит результата устанавливается в 1, в противном случае результирующий бит равен 0.

Операция поразрядного исключающего ИЛИ (^) сравнивает каждый бит первого операнда с соответствующими битами второго операнда. Если один из сравниваемых битов равен 0, а второй бит равен 1, то соответствующий бит результата устанавливается в 1, в противном случае, т.е. когда оба бита равны 1 или 0, бит результата устанавливается в 0.

Пример.

001 $int = 17919 *0100 0101 1111 1111

002 $int2=255 *0000 0000 1111 1111

003 $res = $int ^ $int2 *0100 0101 0000 0000

004 $res = $int | $int2 *0100 0101 1111 1111

005 $res = $int & $int2 *0000 0000 1111 1111

Операции отрицания.

Операция арифметического отрицания (-) вырабатывает отрицание своего операнда. Операнд должен быть целой величиной. При выполнении осуществляются обычные арифметические преобразования.

Пример:

001 $int = 5

002 $int= - $int *Значение $int = -5

Операция логического отрицания "НЕ" (!) вырабатывает значение 0, если операнд есть истина (не нуль), и значение 1, если операнд равен нулю (0).

Пример:

001 $int = 5

002 $int= ! $int *Значение 0 [FALSE] т.к. $int Истина

Операция двоичного отрицания (~) вырабатывает двоичное отрицание своего операнда. Операнд должен быть целого типа. Осуществляется обычное арифметическое преобразование, все биты операнда инвертируются.

Пример:

001 $int = 17919 *0100 0101 1111 1111

002 $int=~$int *1011 1010 0000 0000

v Операторы условного перехода

Операторы условного перехода используются для того, чтобы изменить последовательность выполнения команд в скрипте в зависимости от определенного условия. Простейшим примером оператора условного перехода может служить оператор «if» применяющийся в паре с оператором «end». Логика его работы следующая:

if (выражение принимающее значение «Истина» или «Ложь»)

операторы, исполняющиеся в случае, если выражение принимает значение «Истина»

end

Пример:

210 if [HOMEBASE]

220 @ = [THIS] -> fly to homebase

230 end

В строке 210 проверяется, задана ли база для данного корабля. Если она установлена (функция [HOMEBASE] вернула значение, которое может быть интерпретировано как «Истина»), то управление переходит в строку 220, где корабль получает команду возвращаться на неё. Поскольку нам может быть необходимо, чтобы при выполнении определенного условия исполнялся не один, а целая группа операторов, мы должны указать, где именно заканчивается эта группа. Для этой цели и служит оператор «end». Оператор «if» может принимать и более сложные формы:

if (выражение, принимающее значение «Истина» или «Ложь»)

операторы, исполняющиеся в случае, если выражение принимает значение «Истина»

else

операторы, исполняющиеся в случае, если выражение принимает значение «Ложь»

end

if not (выражение, принимающее значение «Истина» или «Ложь»)

операторы исполняющиеся в случае если выражение принимает значение «Ложь»

else

операторы исполняющиеся в случае если выражение принимает значение «Истина»

end

if (выражение1, принимающее значение «Истина» или «Ложь»)

операторы исполняющиеся в случае, если выражение1 принимает значение «Истина»

else if (выражение2, принимающее значение «Истина» или «Ложь»)

операторы исполняющиеся в случае, если выражение1 принимает значение «Ложь», а выражение2 принимает значение «Истина»

else

операторы исполняющиеся в случае, если выражение1 принимает значение «Ложь» и выражение2 принимает значение «Ложь»

end

if not (выражение1, принимающее значение «Истина» или «Ложь»)

операторы исполняющиеся в случае, если выражение1 принимает значение «Ложь»

else if not (выражение2, принимающее значение «Истина» или «Ложь»)

операторы, исполняющиеся в случае, если выражение1 принимает значение «Истина» а выражение2 принимает значение «Ложь»

else

операторы, исполняющиеся в случае, если выражение1 принимает значение «Истина» и выражение2 принимает значение «Истина»

end

skip if (выражение, принимающее значение «Истина» или «Ложь»)

оператор, исполняющийся в случае, если выражение принимает значение «Ложь»

В данной форме записи оператора «if» оператор «end» не требуется, поскольку в случае если выражение принимает значение «Истина» пропускается (не выполняется) только один оператор (не группа операторов), следующий в строке сразу за «skip if»

skip if not (выражение принимающее значение «Истина» или «Ложь»)

оператор, исполняющийся в случае, если выражение принимает значение «Истина»

v Операторы безусловного перехода

К операторам безусловного перехода относится оператор «goto label», который используется для перехода к определенной строке скрипта. Прежде чем использовать «goto label» необходимо объявить метку для строки, в которую мы хотим осуществить переход. Делается это при помощи оператора «define label» из раздела «Общие команды=>Команды исполнения».

Пример:

100 StartCalculation:

110 $Total = $Price * $Amount

120 …

…

430 goto label StartCalculation

Само ключевое слово «define label» в тексте скрипта не указывается, вместо него указывается имя метки со знаком «:» – двоеточие после него. Будьте особенно внимательны используя конструкцию «define label» «goto label» так как с её помощью очень легко получить «вечный» цикл, т.е. закольцованный кусок программы, выход из которого не предусмотрен, а при отсутствии в сегменте кода между меткой и оператором goto команд wait и команд со знаком @ произойдет зависание игры.

Х2 help Dimaxx & Pegasus script MAD_Kuzia

v Циклы

Принципы использование циклов

Циклы используются для повторения действия (или последовательности действий) нужное нам кол-во раз. Сколько в цикле будет витков (проходов цикла), определяется условием цикла. В развитых языках программирования существуют циклы 3-х типов: с проверкой условия в начале, с проверкой условия в конце и итерационные (с явно заданным кол-вом витков). В принципе, все они являются взаимозаменяемыми, однако выделены в разные типы для нашего удобства. Скриптовый движок Х2 использует только один тип цикла – с проверкой условия в начале.

Бывает 2-х видов:

while <условие>

…

end

Этот цикл выполняется, пока условие имеет значение “Истина” (TRUE).

while not <условие>

…

end

Этот цикл выполняется, пока условие имеет значение “Ложь” (FALSE).

В качестве условия могут быть использованы числа, переменные, логические выражения, сложные логические выражения использующие логические операторы AND, OR, сложные вычисляемые выражения, возвращаемые значения инструкций. Оператор цикла While интерпретирует любое значение как логическое значение Истина или Ложь. Истиной является любое значение большее 0, ложью считается значение 0 или null.

Итерационный цикл

Часто возникает ситуация, когда требуется совершить строго заданное кол-во витков цикла, например, отыскать в массиве ячейку с определенным значением. В этом случае кол-во витков цикла должно ограничиваться кол-вом ячеек в массиве (размером массива). Как это сделать, ведь у нас в игре нет специального цикла с итерацией? Как я уже говорил, все типы циклов взаимозаменяемы, и при определенных ухищрениях можно использовать один тип цикла вместо другого. В нашем случае можно ввести специальную переменную-счетчик витков, анализируя значение которой как условие для цикла, мы добьемся того же результата. Например:

001 $count = 0

002 while $count < 20

…

…

007 inc $count =

008 end

Здесь у нас счетчик – переменная $count, которой перед началом цикла мы присваиваем начальное значение 0. Далее мы организуем цикл, который будет продолжаться, пока наш счетчик будет меньше 20. Перед каждым последующим витком цикла мы увеличиваем значение счетчика на 1. Как видите, процесс неложный.

Бесконечный цикл

Это цикл, который выполняется бесконечное число раз, если мы не прервем его специально. Такие циклы широко используются в скриптах для различных команд корабля: торговли, патрулирования и т.п. Например, команда «Продавать товар по лучшей цене» выполняется постоянно, пока мы не прервем ее другой командой. Такие бесконечные циклы организуются просто: достаточно оператору цикла задать в качестве условия заведомо неизменное значение. Например:

while [TRUE]

…

end

или

while 1

…

end

Бесконечные циклы нужно использовать очень аккуратно, внутри них обязательно надо предусматривать временные задержки (команды wait), иначе можно легко «подвесить» игру. Это связано с тем, что все запущенные скрипты выполняются в игре по-очереди, т.к. движок игры основан на принципе «Не вытесняющей многозадачности» (будет рассмотрено в следующей главе). Задержки внутри скриптов позволяют приостановить текущий скрипт и дать в это время возможность выполняться другим скриптам. Если внутри бесконечного цикла не будет задержки (или вызова команды, которая имеет свои задержки, команды перед которыми стоит значок @), то этот скрипт захватит все процессорное время и подвесит игру.

Бесконечный цикл можно получить ненарочно, задав некорректное условие оператору цикла. Например:

while $a !=1 OR $a = 1

…

end

Здесь цикл будет выполняться при любом значении $а, что приведет к бесконечному “зацикливанию”. Зацикливание можно получить в итерационном цикле (см. пример выше), забыв изменить значение счетчика (оператор inc). Ошибочных вариантов много, всех не перечислишь, поэтому всегда будьте внимательны с циклами, условными и бесконечными, тщательно все продумывайте, чтобы не получилось неприятностей. И возьмите за правило, добавлять в тело любого цикла команду wait с небольшой задержкой, это убережет игру от зависания в случае некорректного условия и сохранит возможность принудительной остановки некорректно работающего скрипта.

Дополнительное управление циклами

Скриптовый язык Х2 имеет, подобно прочим языкам, команды break и continue. Эти команды служат для дополнительного гибкого контроля над циклами. Команда break позволяет в любой (нужный нам) момент прервать текущий цикл, а команда continue – прервать текущий виток и сразу перейти на следующий.

Пример для команды break:

while $i < 40

… последовательность действий 1

skip if $i != 20

break

… последовательность действий 2

end

Здесь цикл будет выполняться, пока $i меньше 40, и принудительно прервется, если $i станет равным 20. При этом успеет выполнится последовательность действий 1, а до последовательности действий 2 дело не дойдет.

Пример для команды continue:

while $i < 40

… последовательность действий 1

skip if $i != 20

continue

… последовательность действий 2

end

Здесь цикл будет выполняться, пока $i меньше 40, и принудительно начнется новый его виток, если $i станет равным 20. При этом успеет выполнится последовательность действий 1, а последовательность действий 2 – нет.

Также можно прервать текущий цикл, используя операторы безусловного перехода. Например:

while $i < 40

… последовательность действий 1

skip if $i != 20

goto label metka

… последовательность действий 2

end

… последовательность действий 3

metka:

… последовательность действий 4

Здесь цикл будет выполняться, пока $i меньше 40, и принудительно прервется, если $i станет равным 20. При этом успеет выполнится только последовательность действий 1, после чего мы сразу перейдем к последовательности действий 4, минуя последовательность 2, принадлежащую циклу, и последовательность 3, которая наступила бы при нормальном завершении цикла. Как видите, оператор безусловного перехода goto label можно использовать даже более гибко, чем команду break.

Далее давайте рассмотри несколько примеров использования циклов в навигационных скриптах:

И так, циклы используются, когда вам необходимо повторять определенную последовательность команд, пока не будет достигнуто некоторое условие. Конечно, получить зацикленный кусок кода можно и используя операторы безусловного перехода, однако подобный подход не рекомендуется, поскольку он ухудшает читаемость кода, к тому же использовать команды цикла гораздо удобнее и проще. Вот пример простейшего цикла:

010 while [ENVIRONMENT] != [HOMEBASE]

011 @=wait randomly from 5000 to 10000 ms

012 @=[THIS] ->fly to home base

013 end

В строке 010, заголовке цикла («while»), задано условие цикла (пока корабль не пристыкован к своей базе), пока оно истинно, т.е. принимает значение «истина», цикл выполняется, т.е. выполняются строки с номерами 011 и 012 (ждать 5-10 сек, возвращаться на базу). Как только выполнение скрипта доходит до строки 013, управление передается в строку 010, проверяется условие и если оно выполняется (принимает значение «истина»), то снова выполняются строки 011 и 012, и так до тех пор, пока условие не примет значение «ложь». Как только условие становится ложно, управление переходит в строку, следующую за «end». Если срока с ключевым словом «end» последняя в скрипте, выполнение скрипта завершается. Однако нам может понадобится выйти из цикла до того как условие цикла примет значение «ложь» (например, базу уничтожили, в этом случае корабль никогда не сядет на свою базу, и цикл окажется «вечным»). Для этих целей служит команда «break». Она передает управление в строку, следующую за «end». С учетом проверки на существование базы наш цикл можно записать следующим образом:

010 while [ENVIRONMENT] != [HOMEBASE]

011 if not [HOMEBASE]

012 break

013 end

014 @ =wait randomly from 5000 to 10000 ms

015 @ =[THIS] ->fly to home base

016 end

Ключевое слово «end» стоящее в строке 013 относится к оператору «if» стоящему в строке 011, «end» всегда относится к ближайшему «if» или «while». Оператор «while» можно записать и как «while not», в этом случае значение выражения, задающего условие цикла, инвертируется. Вот так будет выглядеть предыдущий пример в форме «while not»:

010 while not [ENVIRONMENT] == [HOMEBASE]

011 if not [HOMEBASE]

012 break

013 end

014 @ =wait randomly from 5000 to 10000 ms

015 @ =[THIS] ->fly to home base

016 end


Навигационные команды

v Иерархия объектов

Все объекты с которыми работают скрипты разделяются на классы. Классы могут подразделяться на подклассы углубляясь на несколько уровней вниз. В схеме приведена иерархическая схема подразделения классов и принадлежности к ним объектов.


Навигационные команды

Типы планет.

Всего в Х2 имеется 17 типов планет, доступных инструкции create planet.


Точки входа и флаги состояния сюжетной линии

v Точки входа и флаги состояния сюжетной линии

В таблице указанны все миссии из сюжетной линии и соответствующие им «входные точки» и «флаги состояния» используемые командой <RetVar/IF> is plot <plot> is state <stateflag> для контроля за прохождения игроком сюжетной линии.

Входная точка | Флаг | Описание | Входная точка | Флаг | Описание
1 | 3 | Основное введение | 2 | 18 | AP Gunner миссия
1 | 4 | Получение сообщения от ТерраКорп | 2 | 19 | AP Gunner миссия
1 | 5 | Встреча с ТерраКорп | 2 | 20 | Полет к Black Hole Sun
1 | 6 | Принятие миссии поставки | 2 | 21 | Провал AP Gunner миссии
1 | 7 | Получение сообщения о миссии | 2 | 22 | Получение сообщения от Бена Данны
1 | 8 | Выполнение миссии поставки | 3 | 3 | Войти в контакт с Беном Данна
1 | 9 | Брифинг о транспортной миссии | 3 | 4 | Связаться с капитаном авианосца в Ore Belt
1 | 10 | Принятие транспортной миссии | 3 | 5 | Найти астероид с зондом
1 | 11 | Сообщение относительно миссии | 3 | 6 | Указания по разрушению зонда
1 | 12 | Принятие пассажира на борт | 3 | 7 | Зонд успешно разрушен
1 | 13 | Атака пиратов | 3 | 8 | Указания собрать части зонда
1 | 14 | Спасение неизвестным кораблем | 3 | 9 | Удачный подбор частей зонда
1 | 15 | Миссия провалена | 3 | 10 | Отчет о возвращении капитану авианосца
1 | 16 | Пассажир успешно доставлен | 3 | 11 | Возвращение и отчет перед Беном Данной
1 | 17 | Активизация Хааков | 3 | 12 | Связь с Саей Хо
1 | 18 | Одна или несколько неудач при выполнении миссий первой входной точки | 3 | 13 | Связь с Ми Тоном
1 | 19 | Миссия для встречи с Бренаном | 3 | 14 | Выплата Ми Тону
2 | 3 | Введение в Хаакскую агресию | 3 | 15 | Получение координат хаакского сектора
2 | 4 | Отправление к вратам в Триумфе Бренана | 3 | 16 | Прыжок в хаакский сектор
2 | 5 | Поиск данных у врат | 3 | 17 | Возвращение к Сае Хо
2 | 6 | Нахождение данных у врат | 3 | 18 | Подбор «черного ящика»
2 | 7 | Инструкции о колете в Antigone Memorial | 3 | 19 | Возвращение с «черным ящиком»
2 | 8 | Посещение Antigone Memorial | 3 | 20 | Инструктаж по полету к Omicron Lyrae
2 | 9 | Установка на корабль Jumpdrive | 3 | 21 | Отражение первой хаакской волны
2 | 10 | Полет к Paranid Prime | 3 | 22 | Получение сообщения от Кайла Бренана
2 | 11 | Покупка приемника | 3 | 23 | Занять места между хааков
2 | 12 | Сопровождение Врета | 3 | 24 | Закрытие хаакских кораблей
2 | 13 | Сопровождение Саи | 3 | 25 | Хаакский линкор стреляет
2 | 14 | AP Gunner миссия | 3 | 26 | Указания о уничтожении силовых генераторов
2 | 15 | AP Gunner миссия | 3 | 27 | Силовой генератор уничтожен
2 | 16 | AP Gunner миссия | 3 | 28 | Линкор уничтожен
2 | 17 | AP Gunner миссия | 3 | 29 | Церемония награждения


Приложение

v Симплы "X2 The Threat" .

Симплы короткие звуковые файлы с разными аудио эффектами воспроизводимые командой из раздела «Аудио команды» play sample <Var/Number> . Ниже в таблице приведены номера симплов их длина в секундах и описание. В колонке доступ указанно доступен ли симпл для команды, т.к. ScE к сожалению позволяет воспроизводить не все имеющиеся в "X2 The Threat" симплы. Описание симплов это частично перевод названий взятых из «The X. MSCI Programmer's Handbook», но в основном на слух. Поэтому возможны расхождения в трактованиях.

# | Длина | Описание | Доступ
102 | 0.67 | Шум двигателя (Capital ships) | Нет
103 | 1.02 | Шум двигателя (Argon/Boron/XeНетn M3) | Нет
104 | 1.45 | Шум двигателя (All M4 except Khaak) | Нет
105 | 1.46 | Шум двигателя (Boron/Split TP, All M5 except Khaak) | Нет
106 | 2.00 | Шум двигателя (Argon/Paranid/Teladi TP, All TS, Goner Ship) | Нет
107 | 2.37 | Шум двигателя (Paranid/Split/Teladi/Pirate M3) | Нет
108 | 1.95 | Окружающий звук станции | Нет
109 | 0.90 | Шум двигателя (UFO/Spacefly) | Нет
110 | 0.74 | Шум двигателя (UnkНетwn)/Dynamo | Нет
111 | 0.16 | Выстрел (Khaak laser) | Нет
112 | 1.71 | Шум двигателя (Missile) | Нет
113 | 0.92 | Выстрел (Ion Disruptor) | Нет
114 | 1.45 | Шум двигателя (Khaak M3, M4, M5) | Нет
903 | 1.02 | Удар корпусом (без щита) | Да
904 | 1.42 | Удар корпусом (с щитом) | Да
906 | 1.02 | Удар корпусом (Нет shields) – идентичен 903 | Да
907 | 1.12 | Попадание из оружия (IRE, Alpha PSG) | Да
908 | 1.30 | Попадание из оружия (PAC, Beta PSG) | Да
909 | 1.59 | Попадание из оружия (HEPT/PPC, Gamma PSG) | Да
912 | 0.44 | Выстрел (Alpha IRE) | Да
913 | 0.73 | Выстрел (Beta IRE) | Да
914 | 0.65 | Выстрел (Gamma IRE) | Да
915 | 1.33 | Запуск малой ракеты (Mosquito/Wasp) | Да
916 | 2.11 | Запуск средней ракеты (Dragonfly/Silkworm) | Да
917 | 3.80 | Запуск тяжелой ракеты (Hornet) | Да
918 | 1.70 | Взрыв ракеты или небольшого корабля | Да
919 | 1.41 | Взрыв M6 | Да
920 | 6.42 | Взрыв станции или большого корабля | Да
922 | 2.97 | Белый шум | Да
923 | 0.76 | Тревога (обнаружен враг) | Да
924 | 0.39 | Электрический зуммер | Да
925 | 0.75 | Тревога (приближается ракета) | Да
928 | 0.25 | Высокий электрический зуммер | Да
929 | 1.13 | Какойто резкий полуэлектрический полумеханический звук | Да
930 | 0.29 | Выключение радио | Да
931 | 0.42 | Звук радио | Да
932 | 0.36 | Включение радио | Да
934 | 5.00 | Приближаюшийся шум двигателя | Да
935 | 0.90 | Фоновый шум двигателя | Да
936 | 2.55 | Удаляющийся шум двигателя | Да
937 | 3.80 | Машинный фон | Да
938 | 3.42 | Машинный фон | Да
940 | 0.55 | Машинный фон | Да
943 | 1.61 | Лязг на станции | Да
944 | 0.76 | Электро мотор | Да
945 | 3.76 | Закрывание/открывание дверей с эхом | Да
946 | 1.57 | Эффект реактивного двигателя | Да
949 | 3.59 | Фон внутри кабины | Да
950 | 5.38 | Фоновый машинный звук | Да
951 | 3.64 | Фоновый звук реактора | Да
952 | 2.48 | Фоновый машинный звук | Да
953 | 0.54 | Звуки меню (menu on) | Да
954 | 0.54 | Звуки меню (menu off) | Да
955 | 0.28 | Звуки меню (select) | Да
956 | 0.27 | Звуки меню (error) | Да
957 | 0.11 | Звуки меню (cursoring) | Да
958 | 0.67 | Выстрел (Alpha PAC) | Да
959 | 0.99 | Выстрел (Beta/Gamma PAC) | Да
960 | 0.67 | Выстрел (PPC/HEPT) | Да
961 | 26.52 | Переговоры пилотов в эфире | Да
962 | 1.05 | Электрическая вибрация | Да
963 | 1.39 | Docking arms extending (cut scene) | Да
964 | 2.50 | Открытие грузового отсека | Да
965 | 3.42 | Ракета на хим.топливе | Да
966 | 3.22 | Сканер | Да
967 | 4.04 | Электрический гул, ребота механизмов | Да
968 | 0.23 | Меню открытие окна | Да
969 | 1.64 | Закрытие грузового отсека | Да
970 | 1.71 | Металлический лязг, запуск промышленного двигателя | Да
971 | 0.76 | Эффект электрической дуги | Да
972 | 0.29 | Короткий гудок | Да
973 | 17.10 | Ракета на хим.топливе (более длинный чем 965) | Да
974 | 15.97 | Мотор/лифт/энергетическое поле с затуханием | Да
975 | 10.80 | Запуск, работа и остановка двигателя | Да
976 | 16.04 | Приближение и удаление сверхзвукового самолета | Да
977 | 5.61 | Выключение двигателя | Да
978 | 21.26 | Мощная турбина (взлетающий реактивный самолет) | Да
979 | 0.48 | Переключение камер | Да
980 | 0.61 | Тревога повышение мощности | Да
981 | 1.22 | Тревога падение мощности | Да
982 | 0.11 | Звуки камеры | Да
983 | 8.71 | Затихающая машина | Да
984 | 12.84 | Большой взрыв / Гром | Да
985 | 0.27 | Звук компьютера (используется скрипте Engine Booster) | Да
986 | 0.02 | Короткий компьютерный звук | Да
987 | 0.35 | Изменение размера карты сектора | Да
988 | 0.27 | Звук компьютера (более длинный чем 985) | Да
989 | 0.40 | Выход из карты сектора | Да
990 | 3.40 | Пневматический пресс | Да
991 | 3.86 | Транспортер | Да
992 | 0.32 | Раздавленный жук | Да
993 | 21.33 | Тяжелое дыхание в скафандре | Да
994 | 16.00 | Тяжелое дыхание в скафандре короткое | Да
995 | 0.62 | Зум видео камеры | Да
996 | 1.03 | Зум видео камеры длинный | Да
997 | 10.19 | Пневматика выпуск шасси | Да
998 | 5.16 | Конвеер | Да
1000 | 9.34 | Разбивается стекло скафандра | Да
1001 | 1.41 | Эффект механического прсса | Да
1002 | 1.27 | Фреза | Да
1003 | 13.84 | Чужая планета фон | Да
1004 | 14.30 | Бульканье в болоте | Да
1005 | 9.43 | Электрическое поле | Да
1006 | 1.37 | Прибытие на станцию | Да
1007 | 2.25 | Новости на станции | Да
1008 | 3.22 | Поступило новое сообщение | Да
1100 | 3.95 | Продвижение рейтинга | Да
1101 | 2.85 | Удаленное электрическое рычание | Да
1102 | 1.21 | Электрический гул | Да
1103 | 0.19 | Далекий писк | Да
1104 | 8.19 | Механический лязг | Да
1105 | 2.40 | Ревебрирующий электрический «белый шум» | Да
1106 | 4.72 | Модулированный электрический фон с эфферком развертывания и сворачивания | Да
1107 | 6.83 | Тяжелое дыхание | Да
1108 | 8.19 | Ветер в наушниках | Да
1109 | 4.51 | Далекий металлический удар (напоминает забивание сваи) | Да
1110 | 2.75 | Короткий фоновый толчок | Да
1111 | 55.72 | Придбежающийся из далека шум похожий на шум железной дороги | Да
1112 | 31.50 | Пролетающий мимо большой корабль | Да
1113 | 7.49 | Пневматический запуск и ускорение | Да
1114 | 0.32 | Ввод кода открытие дверей | Да
1115 | 2.77 | Пневматические ворота | Да
1116 | 0.12 | Эффер маханического цеха | Да
1117 | 5.89 | Приглушенный звук конвеера | Да
1118 | 1.59 | Модулированный сигнал | Да
1119 | 0.13 | Альтернативный звук полета (used in Engine Booster script) | Да
1120 | 0.24 | Клик | Да
1121 | 60.55 | Сверление дробление | Да
1122 | 100.46 | Эффект напоминает скрип металла подвесного моста движущиеся по нему машины | Да
1123 | 18.09 | Легкий шум в далеко звук радио | Да
1124 | 0.61 | Динг донг | Да
1125 | 3.50 | Сервопривод | Да
1126 | 0.40 | Электрическое открытие/закрытие люка | Да
1127 | 1.44 | Пневматика и приглушенный удар по металу | Да
1128 | 2.53 | Металический сверление | Да
1129 | 1.75 | Сигнал | Да
1130 | 1.02 | Замаок электро ворот | Да
1131 | 52.69 | Печатная машинка | Да
1132 | 4.99 | Фон радиорубки | Да
1133 | 2.42 | Компьютерный колокол | Да
1134 | 0.75 | Электрический зуммер звонок | Да
1135 | 0.43 | Электрические щелчки | Да
1136 | 0.43 | Нажатие кнопки | Да
1137 | 2.56 | Нажатие кнопки | Да
1138 | 4.47 | Индустриальный фон | Да
1139 | 6.35 | Индустриальный фон с удаленным клацканьем | Да
1140 | 8.18 | Звук радио эфира | Да
1141 | 35.96 | Какоето бульканье | Да
1142 | 4.28 | Металлическое клацканье/стук по металу | Да
1143 | 18.38 | Скрип металла подводной лодки в тишине | Да
1144 | 4.07 | Эффект стреляющего оружия или защитного механизма | Да
1145 | 8.07 | Фон электроники | Да
1146 | 8.04 | Фон электроники | Да
1147 | 7.03 | Неприятный эжектрический звук похож на чтото хаакское | Да
1148 | 13.39 | Сильный взрыв с отголосками | Да
1149 | 4.08 | Механическо-пневматический запуск | Да
1150 | 3.77 | Удаленный взрыв | Да
1151 | 1.00 | Тихий удар | Да
1152 | 2.33 | Артелерийский выстрел | Да
1153 | 2.00 | Артелерийский выстрел удаленный | Да
1154 | 4.40 | Взрыв | Да
1155 | 4.00 | Удаленный взрыв с эхом | Да
1156 | 0.34 | Быстро пролетевший обект | Да
1157 | 0.44 | Эффект механо-электронной системы | Да
1158 | 1.44 | Человеческий крик от боли | Да
1159 | 6.05 | Лязг аврийный (разрушение внутри станции) | Да


Навигационные команды

v Описание Специальных объектов

В таблице собраны объекты создаваемые инструкцией create special, в первой колонке указан тип задаваемый инструкции в параметре type. Колонка «Наведение» указывает возможно ли на этот объект навести систему наведения (поймать в прицел). «Голосовое имя» - это фраза произносимая бортовым компьютером при наведении на данный объект. В конце таблицы приведены ссылки на визуальные картинки объектов (выкопировка из MSCI Programmer’s Handbook).

Тип | Наведение | Голосовое имя | Описание
0 | Да | Kessler Ring (Кольцо Кеслера) | Кольцо Кеслера
1 | Да | Kessler Ring (Кольцо Кеслера) | Кольцо Кеслера
2 | Да | Unknown object (Неизвестный объект) | Передняя часть корабля Xenon K
3 | Да | Asteroid (Астероид) | Астероид
4 | Да | Asteroid (Астероид) | Астероид
5 | Да | Unknown object (Неизвестный объект) | Часть стены анимированной станции из X-Tension
6 | Да | Unknown object (Неизвестный объект) | Части конструкций анимированной станции из X-Tension
7 | Да | Unknown object (Неизвестный объект) | Часть стены анимированной станции из X-Tension
8 | Да | Unknown object (Неизвестный объект) | Часть анимированной станции из X-Tension
9 | Да | Unknown object (Неизвестный объект) | Стыковочная часть верфи или дока
10 | Да | Unknown object (Неизвестный объект) | Покрытие
11 | Да | Unknown object (Неизвестный объект) | Значок карты сектора
12 | Да | Unknown object (Неизвестный объект) | Post-like object
13 | Да | Unknown object (Неизвестный объект) | Двигательный отсек
14 | Да | Unknown object (Неизвестный объект) | Подсвечиваемый обломок
15 | Да | Unknown object (Неизвестный объект) | Астероид с тунелем
16 | Да | Unknown object (Неизвестный объект) | Gravidar (an actual working copy of your ship's gravidar)
17 | Да | Unknown object (Неизвестный объект) | Кольца Кеслера
18 | Да | Unknown object (Неизвестный объект) | Кольца Кеслера
19 | Да | Unknown object (Неизвестный объект) | Finish line?
20 | Нет |  | Некие объекты используемые при оформлении других объектов
21 | Нет |  | Некие объекты используемые при оформлении других объектов
22 | Нет |  | Некие объекты используемые при оформлении других объектов
23 | Нет |  | Некие объекты используемые при оформлении других объектов
24 | Да | Nacelle | Обтекатель врат
25 | Да | Nacelle | Элемент врат
26 | Да | Nacelle | Обтекатель врат
27 | Да | Gate (Врата) | Разрушенное кольцо врат
28 | Да |  | Малый астероид
29 | Нет |  | Непонятно что
30 | Да | Ship debris (обломки корабля) | Обломки Сплитского Дракона (Разрушенный корабль Кайла Бренана)
31 | Нет |  | Обломки
32 | Нет |  | Обломки
33 | Нет |  | Обломки
34 | Да | Navigational beacon (Навигационный маяк) | Навигационный спутник
35 | Нет |  | Хаакские обломки
36 | Нет |  | Обломки
37 | Да | Unknown object (Неизвестный объект) | Хаакские обломки
38 | Да | Station debris (обломки станции) | Разрушенная станция (President's End)
39 | Да | Station debris (обломки станции) | Разрушенная станция (President's End)
40 | Да | Ship debris (обломки корабля) | Разрушенная станция (President's End)
41 | Да | Station debris (обломки станции) | Разрушенная станция (President's End)
42 | Да | Station debris (обломки станции) | Разрушенная станция (President's End)
43 | Да | Ship debris (обломки корабля) | Обломки Аргонского Титана
44 | Да |  | Грузовой люк с другими деталями
45 | Да |  | Окно
46 | Да |  | Плазменная панель с бегущими цифрами
47 | Да |  | Встроенный туннель
48 | Да |  | То же самое, что и 44
49 | Да |  | Кольцо
50 | Да |  | Туннель
51 | Да |  | 3d указатель точки
52 | Да |  | Туннель
53 | Да |  | То же самое, что и 44
54 | Да |  | Некие объекты используемые при оформлении других объектов
55 | Да |  | Туннель
56 | Да |  | Некие объекты используемые при оформлении других объектов
57 | Да |  | Некие объекты используемые при оформлении других объектов
58 | Да |  | Некие объекты используемые при оформлении других объектов
59 | Да |  | Некие объекты используемые при оформлении других объектов
60 | Да |  | Грузовой люк
61 | Да |  | Сфера
62 | Да |  | Некие объекты используемые при оформлении других объектов
63 | Да |  | Небольшое белое облако
64 | Да |  | Некие объекты используемые при оформлении других объектов
65 | Да |  | Красный навигационный маяк
66 | Да |  | Грузовой контейнер
67 | Да |  | Некие объекты используемые при оформлении других объектов
68 | Да |  | Некие объекты используемые при оформлении других объектов
69 | Да |  | То же самое, что и 44
70 | Да |  | Некие объекты используемые при оформлении других объектов
71 | Да |  | Некие объекты используемые при оформлении других объектов
72 | Да |  | 3d указатель точки, то же самое, что и 51
73 | Да |  | То же самое, что и 44

Специальные объекты с 0 по 14

Специальные объекты с 15 по 32

Специальные объекты с 33 по 49

Специальные объекты с 50 по 73


Навигационные команды

v Сводная таблица типов и подтипов товаров и объектов.

Здесь представлена сводная таблица всех Типов и подтипов и относящиеся к ним товары и объекты. Если, в списке напротив maintype и subtype находиться пустая строка, то это говорит о том, что данный подтип недоступен ScE. ReadText, инфорирует о том, что данный субтип зарезервирован для какого либо скрипта, и доступен для изменения. Все объекты описываются в специальных файлах описателях находящихся в папке \types, в не распакованной версии игры расширение этих файлов pck, в распакованной txt.

Товар | maintype | subtype
Maintype 5 (Торговые станции, доки не производящие товары, а только продающие) файл типов TDocks.pck
Аргонская торговая станция | 5 | 0
Сплитский торговый порт | 5 | 1
Паранидский торговый док | 5 | 2
Королевская торговая станция | 5 | 3
Теладийская торговая станция | 5 | 4
Ксенонская Станция | 5 | 5
Аргонский док оборудования | 5 | 6
Сплитский док оборудования | 5 | 7
Паранидский док оборудования | 5 | 8
Королевский док оборудования | 5 | 9
Теладийский док оборудования | 5 | 10
Ксенонская Станция | 5 | 11
Неизвестный объект | 5 | 12
Храм Гонеров | 5 | 13
Пиратская база | 5 | 14
ReadText17-4101 | 5 | 15
Неизвестная вражеская станция | 5 | 16
Maintype 6 (Фабрики, заводы, малые верфи производящие товары) файл типов TFactories.pck
Аргон Верфь Федерации Аргон | 6 | 0
Сплит Сплитская верфь | 6 | 1
Паранид Паранидская верфь | 6 | 2
Борон Верфь Королевства Борон | 6 | 3
Телади Теладийская верфь | 6 | 4
Аргон Оружейный завод | 6 | 5
Аргон Фабрика кристаллов | 6 | 6
Аргон Фабрика квантовых трубок | 6 | 7
Аргон Фабрика микросхем | 6 | 8
Аргон Компьютерный завод | 6 | 9
Сплит Оружейный завод | 6 | 10
Сплит Фабрика кристаллов | 6 | 11
Сплит Фабрика квантовых трубок | 6 | 12
Сплит Фабрика микросхем | 6 | 13
Сплит Компьютерный завод | 6 | 14
Паранид Оружейный завод | 6 | 15
Паранид Фабрика кристаллов | 6 | 16
Паранид Фабрика квантовых трубок | 6 | 17
Паранид Фабрика микросхем | 6 | 18
Паранид Компьютерный завод | 6 | 19
Борон Оружейный завод | 6 | 20
Борон Фабрика кристаллов | 6 | 21
Борон Фабрика квантовых трубок | 6 | 22
Борон Фабрика микросхем | 6 | 23
Борон Компьютерный завод | 6 | 24
Телади Оружейный завод | 6 | 25
Телади Фабрика кристаллов | 6 | 26
Телади Фабрика квантовых трубок | 6 | 27
Телади Фабрика микросхем | 6 | 28
Телади Компьютерный завод | 6 | 29
Аргон Фабрика 1МВт щитов | 6 | 30
Аргон Фабрика 5МВт щитов | 6 | 31
Аргон Фабрика 25МВт щитов | 6 | 32
Аргон Фабрика 125МВт щитов | 6 | 33
Сплит Фабрика 1МВт щитов | 6 | 34
Сплит Фабрика 5МВт щитов | 6 | 35
Сплит Фабрика 25МВт щитов | 6 | 36
Сплит Фабрика 125МВт щитов | 6 | 37
Паранид Фабрика 1МВт щитов | 6 | 38
Паранид Фабрика 5МВт щитов | 6 | 39
Паранид Фабрика 25МВт щитов | 6 | 40
Паранид Фабрика 125МВт щитов | 6 | 41
Борон Фабрика 1МВт щитов | 6 | 42
Борон Фабрика 5МВт щитов | 6 | 43
Борон Фабрика 25МВт щитов | 6 | 44
Борон Фабрика 125МВт щитов | 6 | 45
Телади Фабрика 1МВт щитов | 6 | 46
Телади Фабрика 5МВт щитов | 6 | 47
Телади Фабрика 25МВт щитов | 6 | 48
Телади Фабрика 125МВт щитов | 6 | 49
Аргон Фабрика ракет Москит | 6 | 50
Аргон Фабрика ракет Оса | 6 | 51
Аргон Фабрика ракет Стрекоза | 6 | 52
Аргон Фабрика ракет Шелкопряд | 6 | 53
Аргон Фабрика ракет Шершень | 6 | 54
Сплит Фабрика ракет Москит | 6 | 55
Сплит Фабрика ракет Оса | 6 | 56
Сплит Фабрика ракет Стрекоза | 6 | 57
Сплит Фабрика ракет Шелкопряд | 6 | 58
Сплит Фабрика ракет Шершень | 6 | 59
Паранид Фабрика ракет Москит | 6 | 60
Паранид Фабрика ракет Оса | 6 | 61
Паранид Фабрика ракет Стрекоза | 6 | 62
Паранид Фабрика ракет Шелкопряд | 6 | 63
Паранид Фабрика ракет Шершень | 6 | 64
Борон Фабрика ракет Москит | 6 | 65
Борон Фабрика ракет Оса | 6 | 66
Борон Фабрика ракет Стрекоза | 6 | 67
Борон Фабрика ракет Шелкопряд | 6 | 68
Борон Фабрика ракет Шершень | 6 | 69
Телади Фабрика ракет Москит | 6 | 70
Телади Фабрика ракет Оса | 6 | 71
Телади Фабрика ракет Стрекоза | 6 | 72
Телади Фабрика ракет Шелкопряд | 6 | 73
Телади Фабрика ракет Шершень | 6 | 74
Аргон Завод импульсных пушек AIRE | 6 | 75
Аргон Завод импульсных пушек BIRE | 6 | 76
Аргон Завод импульсных пушек GIRE | 6 | 77
Аргон Завод фотонных пушек APAC | 6 | 78
Аргон Завод фотонных пушек BPAC | 6 | 79
Аргон Завод фотонных пушек GPAC | 6 | 80
Аргон Завод плазменных орудий AHEPT | 6 | 81
Аргон Завод плазменных орудий BHEPT | 6 | 82
Аргон Завод плазменных орудий GHEPT | 6 | 83
Сплит Завод импульсных пушек AIRE | 6 | 84
Сплит Завод импульсных пушек BIRE | 6 | 85
Сплит Завод импульсных пушек GIRE | 6 | 86
Сплит Завод фотонных пушек APAC | 6 | 87
Сплит Завод фотонных пушек BPAC | 6 | 88
Сплит Завод фотонных пушек GPAC | 6 | 89
Сплит Завод плазменных орудий AHEPT | 6 | 90
Сплит Завод плазменных орудий BHEPT | 6 | 91
Сплит Завод плазменных орудий GHEPT | 6 | 92
Паранид Завод импульсных пушек AIRE | 6 | 93
Паранид Завод импульсных пушек BIRE | 6 | 94
Паранид Завод импульсных пушек GIRE | 6 | 95
Паранид Завод фотонных пушек APAC | 6 | 96
Паранид Завод фотонных пушек BPAC | 6 | 97
Паранид Завод фотонных пушек GPAC | 6 | 98
Паранид Завод плазменных орудий AHEPT | 6 | 99
Паранид Завод плазменных орудий BHEPT | 6 | 100
Паранид Завод плазменных орудий GHEPT | 6 | 101
Борон Завод импульсных пушек AIRE | 6 | 102
Борон Завод импульсных пушек BIRE | 6 | 103
Борон Завод импульсных пушек GIRE | 6 | 104
Борон Завод фотонных пушек APAC | 6 | 105
Борон Завод фотонных пушек BPAC | 6 | 106
Борон Завод фотонных пушек GPAC | 6 | 107
Борон Завод плазменных орудий AHEPT | 6 | 108
Борон Завод плазменных орудий BHEPT | 6 | 109
Борон Завод плазменных орудий GHEPT | 6 | 110
Телади Завод импульсных пушек AIRE | 6 | 111
Телади Завод импульсных пушек BIRE | 6 | 112
Телади Завод импульсных пушек GIRE | 6 | 113
Телади Завод фотонных пушек APAC | 6 | 114
Телади Завод фотонных пушек BPAC | 6 | 115
Телади Завод фотонных пушек GPAC | 6 | 116
Телади Завод плазменных орудий AHEPT | 6 | 117
Телади Завод плазменных орудий BHEPT | 6 | 118
Телади Завод плазменных орудий GHEPT | 6 | 119
Аргон Рудодобывающая шахта | 6 | 120
Сплит Рудодобывающая шахта | 6 | 121
Паранид Рудодобывающая шахта | 6 | 122
Борон Рудодобывающая шахта | 6 | 123
Телади Рудодобывающая шахта | 6 | 124
Аргон Кремниедобывающая шахта | 6 | 125
Сплит Кремниедобывающая шахта | 6 | 126
Паранид Кремниедобывающая шахта | 6 | 127
Борон Кремниедобывающая шахта | 6 | 128
Телади Кремниедобывающая шахта | 6 | 129
Аргон Солнечная электростанция | 6 | 130
Сплит Солнечная электростанция | 6 | 131
Паранид Солнечная электростанция | 6 | 132
Борон Солнечная электростанция | 6 | 133
Телади Солнечная электростанция | 6 | 134
Аргон Пшеничная ферма | 6 | 135
Аргон Аргонское ранчо | 6 | 136
Борон Ферма планктона | 6 | 137
Борон Фабрика биогаза | 6 | 138
Сплит Ферма скруффинов | 6 | 139
Сплит Космический челт-аквариум | 6 | 140
Паранид Соевая ферма | 6 | 141
Паранид Улиточное ранчо | 6 | 142
Телади Цветочная ферма | 6 | 143
Телади Теладианиумный завод | 6 | 144
Телади Фабрика грез | 6 | 145
Аргон Фабрика раймс | 6 | 146
Аргон Кахунопекарня | 6 | 147
Аргон Перегонный завод | 6 | 148
Борон Стотт фабрика | 6 | 149
Борон Лаборатория бофу | 6 | 150
Сплит Мельница массома | 6 | 151
Сплит Растарный завод | 6 | 152
Паранид Ювелирный завод | 6 | 153
Паранид Соевая фабрика | 6 | 154
Телади Фабрика ностропового масла | 6 | 155
Телади Благодатное местечко | 6 | 156
Ксенон Солнечная электростанция | 6 | 157
Ксенон Верфь ксенонов | 6 | 158
Аргон Фабрика спутников Мк.1 | 6 | 159
Сплит Фабрика спутников Мк.1 | 6 | 160
Паранид Фабрика спутников Мк.1 | 6 | 161
Борон Фабрика спутников Мк.1 | 6 | 162
Телади Фабрика спутников Мк.1 | 6 | 163
Аргон Фабрика мин СКВОШ | 6 | 164
Сплит Фабрика мин СКВОШ | 6 | 165
Паранид Фабрика мин СКВОШ | 6 | 166
Борон Фабрика мин СКВОШ | 6 | 167
Телади Фабрика мин СКВОШ | 6 | 168
Аргон Фабрика защитных башен | 6 | 169
Сплит Фабрика защитных башен | 6 | 170
Паранид Фабрика защитных башен | 6 | 171
Борон Фабрика защитных башен | 6 | 172
Телади Фабрика защитных башен | 6 | 173
Аргон Фабрика боевых дронов | 6 | 174
Сплит Фабрика боевых дронов | 6 | 175
Паранид Фабрика боевых дронов | 6 | 176
Борон Фабрика боевых дронов | 6 | 177
Телади Фабрика боевых дронов | 6 | 178
Аргон Причал Федерации Аргон | 6 | 179
Сплит Сплитская малая верфь | 6 | 180
Паранид Пирс Империи Паранид | 6 | 181
Борон Боронский сухой док | 6 | 182
Телади Теладийская выставка-распродажа | 6 | 183
Аргон Завод мезонных орудий APPC | 6 | 184
Аргон Завод мезонных орудий BPPC | 6 | 185
Аргон Завод мезонных орудий GPPC | 6 | 186
Сплит Завод мезонных орудий APPC | 6 | 187
Сплит Завод мезонных орудий BPPC | 6 | 188
Сплит Завод мезонных орудий GPPC | 6 | 189
Паранид Завод мезонных орудий APPC | 6 | 190
Паранид Завод мезонных орудий BPPC | 6 | 191
Паранид Завод мезонных орудий GPPC | 6 | 192
Борон Завод мезонных орудий APPC | 6 | 193
Борон Завод мезонных орудий BPPC | 6 | 194
Борон Завод мезонных орудий GPPC | 6 | 195
Телади Завод мезонных орудий APPC | 6 | 196
Телади Завод мезонных орудий BPPC | 6 | 197
Телади Завод мезонных орудий GPPC | 6 | 198
Аргон Завод вихревых пушек APSG | 6 | 199
Аргон Завод вихревых пушек BPSG | 6 | 200
Аргон Завод вихревых пушек GPSG | 6 | 201
Сплит Завод вихревых пушек APSG | 6 | 202
Сплит Завод вихревых пушек BPSG | 6 | 203
Сплит Завод вихревых пушек GPSG | 6 | 204
Паранид Завод вихревых пушек APSG | 6 | 205
Паранид Завод вихревых пушек BPSG | 6 | 206
Паранид Завод вихревых пушек GPSG | 6 | 207
Борон Завод вихревых пушек APSG | 6 | 208
Борон Завод вихревых пушек BPSG | 6 | 209
Борон Завод вихревых пушек GPSG | 6 | 210
Телади Завод вихревых пушек APSG | 6 | 211
Телади Завод вихревых пушек BPSG | 6 | 212
Телади Завод вихревых пушек GPSG | 6 | 213
Аргон Завод автоматических пушек MD | 6 | 214
Сплит Завод автоматических пушек MD | 6 | 215
Паранид Завод автоматических пушек MD | 6 | 216
Борон Завод автоматических пушек MD | 6 | 217
Телади Завод автоматических пушек MD | 6 | 218
Аргон Завод аннигиляторов поля ID | 6 | 219
Сплит Завод аннигиляторов поля ID | 6 | 220
Паранид Завод аннигиляторов поля ID | 6 | 221
Борон Завод аннигиляторов поля ID | 6 | 222
Телади Завод аннигиляторов поля ID | 6 | 223
Аргон Фабрика корабельных буров MDS | 6 | 224
Сплит Фабрика корабельных буров MDS | 6 | 225
Паранид Фабрика корабельных буров MDS | 6 | 226
Борон Фабрика корабельных буров MDS | 6 | 227
Телади Фабрика корабельных буров MDS | 6 | 228
Аргон Фабрика кумулятивных боеприпасов | 6 | 229
Сплит Фабрика кумулятивных боеприпасов | 6 | 230
Паранид Фабрика кумулятивных боеприпасов | 6 | 231
Борон Фабрика кумулятивных боеприпасов | 6 | 232
Телади Фабрика кумулятивных боеприпасов | 6 | 233
Аргон Фабрика спутников Мк.2 | 6 | 234
Сплит Фабрика спутников Мк.2 | 6 | 235
Паранид Фабрика спутников Мк.2 | 6 | 236
Аргон Аргонский утилизатор | 6 | 237
Сплит Сплитские торговцы металлоломом | 6 | 238
Паранид Паранидские торговцы вторсырьём | 6 | 239
Борон Королевская восстановительная верфь | 6 | 240
Телади Торговцы ломом Теладийской Компании | 6 | 241
Maintype 7 (Корабли) файл типов TShips.pck
Argon Mammoth | 7 | 0
Argon Mercury | 7 | 1
Argon Colossus | 7 | 2
Argon Titan | 7 | 3
Аргонская Нова-M | 7 | 4
Argon Buster | 7 | 5
Argon Discoverer | 7 | 6
Xenon I | 7 | 7
Xenon H | 7 | 8
ReadText17-3601 | 7 | 9
Xenon J | 7 | 10
Xenon K | 7 | 11
Xenon L | 7 | 12
Xenon M | 7 | 13
Xenon N | 7 | 14
Split Elephant | 7 | 15
ReadText17-3371 | 7 | 16
Split Raptor | 7 | 17
Split Python | 7 | 18
Split Mamba | 7 | 19
Split Scorpion | 7 | 20
ReadText17-3351 | 7 | 21
Paranid Hercules | 7 | 22
Paranid Demeter | 7 | 23
Paranid Zeus | 7 | 24
Paranid Odysseus | 7 | 25
Paranid Perseus | 7 | 26
ReadText17-3441 | 7 | 27
Paranid Pegasus | 7 | 28
Boron Orca | 7 | 29
Boron Dolphin | 7 | 30
Boron Shark | 7 | 31
Boron Ray | 7 | 32
ReadText17-3231 | 7 | 33
ReadText17-3241 | 7 | 34
Boron Octopus | 7 | 35
Teladi Albatross | 7 | 36
Teladi Vulture | 7 | 37
Teladi Condor | 7 | 38
Teladi Phoenix | 7 | 39
Teladi Falcon | 7 | 40
ReadText17-3541 | 7 | 41
ReadText17-3551 | 7 | 42
Pirate Ship | 7 | 43
Pirate Ship | 7 | 44
Pirate Ship | 7 | 45
Pirate Ship | 7 | 46
Pirate Ship | 7 | 47
Pirate Ship | 7 | 48
X-perimental | 7 | 49
Скафандр | 7 | 50
Неизвестный объект | 7 | 51
Goner Ship | 7 | 52
Устройство хранения данных | 7 | 53
Неизвестный объект | 7 | 54
ReadText17-2901 | 7 | 55
Дрон | 7 | 56
Дрон | 7 | 57
Дрон | 7 | 58
Дрон | 7 | 59
ReadText17-3601 | 7 | 60
Pirate Orinoco | 7 | 61
Pirate Bayamon | 7 | 62
Pirate Mandalay | 7 | 63
Навигационный спутник связи | 7 | 64
Мина СКВОШ | 7 | 65
Боевой дрон | 7 | 66
Защитная башня | 7 | 67
Неизвестный объект | 7 | 68
ReadText17-3431 | 7 | 69
Космические мухи | 7 | 70
Неизвестный вражеский корабль (истребитель M3) | 7 | 71
Неизвестный вражеский корабль (истребитель M4) | 7 | 72
Неизвестный вражеский корабль (истребитель M5) | 7 | 73
Неизвестный вражеский корабль (Носитель M1) | 7 | 74
Неизвестный вражеский корабль (Крейсер M2) | 7 | 75
Argon Centaur | 7 | 76
Argon Nova | 7 | 77
ReadText17-3171 | 7 | 78
Argon Express | 7 | 79
Teladi Osprey | 7 | 80
Teladi Buzzard | 7 | 81
Teladi Harrier | 7 | 82
Teladi Toucan | 7 | 83
Split Dragon | 7 | 84
Split Jaguar | 7 | 85
Split Caiman | 7 | 86
Split Iguana | 7 | 87
Boron Hydra | 7 | 88
Boron Barracuda | 7 | 89
Boron Mako | 7 | 90
Boron Manta | 7 | 91
Paranid Nemesis | 7 | 92
Paranid Pericles | 7 | 93
Paranid Demeter | 7 | 94
Paranid Hermes | 7 | 95
ReadText17-4701 | 7 | 96
ReadText17-4711 | 7 | 97
ReadText17-4721 | 7 | 98
Разведывательный дрон | 7 | 99
Навигационный спутник Мк.2 | 7 | 100
Неизвестный корабль | 7 | 101
 | 7 | 102
Неизвестный вражеский корабль | 7 | 103
Неизвестный вражеский корабль | 7 | 104
Неизвестный вражеский корабль | 7 | 105
Неизвестный вражеский корабль | 7 | 106
Маяк | 7 | 107
 | 7 | 108
 | 7 | 109
 | 7 | 110
Неизвестный вражеский корабль | 7 | 111
Неизвестный объект | 7 | 112
Неизвестный объект | 7 | 113
Maintype 8 (Пушки) файл типов TLasers.pck
Импульсная пушка AIRE | 8 | 0
Импульсная пушка BIRE | 8 | 1
Импульсная пушка GIRE | 8 | 2
Фотонная пушка APAC | 8 | 3
Фотонная пушка BPAC | 8 | 4
Фотонная пушка GPAC | 8 | 5
Плазменное орудие AHEPT | 8 | 6
Плазменное орудие BHEPT | 8 | 7
Плазменное орудие GHEPT | 8 | 8
Вихревая пушка APSG | 8 | 9
Вихревая пушка BPSG | 8 | 10
Вихревая пушка GPSG | 8 | 11
Корабельный бур MDS | 8 | 12
Неизвестный объект | 8 | 13
Неизвестный объект | 8 | 14
Неизвестный объект | 8 | 15
Автоматическая пушка MD | 8 | 16
Аннигилятор поля ID | 8 | 17
Мезонное орудие APPC | 8 | 18
Мезонное орудие BPPC | 8 | 19
Мезонное орудие GPPC | 8 | 20
Орудие для защитной башни | 8 | 21
Кионный лазер GKE | 8 | 22
Неизвестный объект | 8 | 23
Maintype 9 (Щиты) файл типов TShields.pck
1МВт щит | 9 | 0
5МВт щит | 9 | 1
25МВт щит | 9 | 2
125МВт щит | 9 | 3
Maintype 10 (Ракеты) файл типов TRockets.pck
Ракета Москит | 10 | 0
Ракета Оса | 10 | 1
Ракета Стрекоза | 10 | 2
Ракета Шелкопряд | 10 | 3
Ракета Шершень | 10 | 4
Неизвестный объект | 10 | 5
Неизвестный объект | 10 | 6
Неизвестный объект | 10 | 7
Maintype 11 (Источники энергии) файл типов TWareE.pck
Батареи | 11 | 0
Maintype 12 (Специальные товары) файл типов TWareN.pck
водяные контейнеры | 12 | 0
артефакты | 12 | 1
искусственные удобрения | 12 | 2
микроорганизмы | 12 | 3
картографические модули | 12 | 4
сборочное оборудование | 12 | 5
компоненты двигателей | 12 | 6
развлекательные модули | 12 | 7
пищевые пайки | 12 | 8
ручное оружие | 12 | 9
деликатесы | 12 | 10
медицинское оборудование | 12 | 11
шахтёрское оборудование | 12 | 12
Нивидиум | 12 | 13
радиоактивные отходы | 12 | 14
обшивка из теладианиума | 12 | 15
модули настройки оружия | 12 | 16
наркотики | 12 | 17
нейроимплант контроля | 12 | 18
яйца космических мух | 12 | 19
пиратское оружие | 12 | 20
хакерские модули | 12 | 21
военный персонал | 12 | 22
пассажиры | 12 | 23
очень важный пассажир | 12 | 24
Maintype 13 (Сырье для производства пищевых продуктов) файл типов TWareB.pck
Отборная пшеница | 13 | 0
Мясо аргну | 13 | 1
Планктон | 13 | 2
Биогаз | 13 | 3
Фрукты скруффин | 13 | 4
Челты | 13 | 5
Соевые бобы | 13 | 6
Улитки майя | 13 | 7
Подсолнечники | 13 | 8
Теладианиум | 13 | 9
Болотная трава | 13 | 10
Maintype 14 (Еда, и ТНП) файл типов TWareF.pck
Ткань раймс | 14 | 0
Бифштексы кахуна | 14 | 1
Космическое топливо | 14 | 2
Стотт специи | 14 | 3
Бофу | 14 | 4
Порошок массом | 14 | 5
Растарное масло | 14 | 6
Маяглит | 14 | 7
Соевая мука | 14 | 8
Ностроповое масло | 14 | 9
Космотабак | 14 | 10
Maintype 15 (Ископаемые минералы) файл типов TWareM.pck
Руда | 15 | 0
Кремниевые пластины | 15 | 1
Нивидиум | 15 | 2
Maintype 16 (Специальные товары и апгрейды) файл типов TWareT.pck
Боеголовки | 16 | 0
Кристаллы | 16 | 1
Квантовые трубки | 16 | 2
Микросхемы | 16 | 3
Компьютерные платы | 16 | 4
Космические мухи | 16 | 5
Пленный | 16 | 6
Навигационный спутник Мк.1 | 16 | 7
Мина СКВОШ | 16 | 8
Защитная башня | 16 | 9
Боевой дрон | 16 | 10
Страховка | 16 | 11
Сканер минералов | 16 | 12
Сканер грузов | 16 | 13
Улучшенный торговый модуль | 16 | 14
 | 16 | 15
Расширение грузового отсека | 16 | 16
Форсирование двигателя | 16 | 17
Оптимизация рулевого управления | 16 | 18
Стыковочный компьютер | 16 | 19
Система анализа движения | 16 | 20
 | 16 | 21
Видеоочки | 16 | 22
Сингулярный компрессор времени (S.E.T.A.) | 16 | 23
Сингулярный компрессор времени (S.E.T.A.) | 16 | 24
Проектор эклиптики | 16 | 25
Аргонская полицейская лицензия | 16 | 26
Боронская полицейская лицензия | 16 | 27
Сплитская полицейская лицензия | 16 | 28
Полицейская лицензия паранидов | 16 | 29
Лицензия СБ Теладийской Компании | 16 | 30
Устройство хранения данных | 16 | 31
Анализатор цен покупки | 16 | 32
Анализатор цен продажи | 16 | 33
Телепортер | 16 | 34
Прыжковый двигатель | 16 | 35
ReadText17-7000803 | 16 | 36
ReadText17-7000903 | 16 | 37
ReadText17-7000703 | 16 | 38
Система жизнеобеспечения | 16 | 39
Ускорители | 16 | 40
Боковые двигатели | 16 | 41
 | 16 | 42
Разведывательный дрон | 16 | 43
Навигационный спутник Мк.2 | 16 | 44
Сборщик руды | 16 | 45
Маскирующее устройство | 16 | 46
 | 16 | 47
 | 16 | 48
Ловушка для космомух | 16 | 49
Кумулятивные боеприпасы | 16 | 50
Гравилокатор Мк.2 | 16 | 51
Гравилокатор Мк.3 | 16 | 52
Навигационный программный модуль Мк.1 | 16 | 53
Торговый программный модуль Мк.1 | 16 | 54
Торговый программный модуль Мк.2 | 16 | 55
Боевой программный модуль Мк.1 | 16 | 56
Боевой программный модуль Мк.2 | 16 | 57
Специальный программный модуль Мк.1 | 16 | 58
ReadText17-5753 | 16 | 59
ReadText17-5763 | 16 | 60
ReadText17-5773 | 16 | 61
ReadText17-5783 | 16 | 62
ReadText17-5793 | 16 | 63
ReadText17-5803 | 16 | 64
ReadText17-5813 | 16 | 65
ReadText17-5823 | 16 | 66
ReadText17-5833 | 16 | 67
ReadText17-5843 | 16 | 68
ReadText17-5853 | 16 | 69
ReadText17-5863 | 16 | 70
Торговый программный модуль Мк.3 | 16 | 71
ReadText17-5883 | 16 | 72
ReadText17-5893 | 16 | 73
ReadText17-5903 | 16 | 74
ReadText17-5913 | 16 | 75
ReadText17-5923 | 16 | 76
ReadText17-5933 | 16 | 77
ReadText17-5943 | 16 | 78
Maintype 17 (Астероиды, субтип соответствует параметрe typе инструкции create asteroid, т.е. визуальному образу астероида) файл типов TAsteroids.pck
Астероид | 17 | 0
Астероид | 17 | 1
Астероид | 17 | 2
Астероид | 17 | 3
Астероид | 17 | 4
Астероид | 17 | 5
Астероид | 17 | 6
Астероид | 17 | 7
Астероид | 17 | 8
Астероид | 17 | 9
Maintype 18 (Врата, начиная с субтипа 0 – Северные, Южные, Западные, Восточные, XenonGate) файл типов TGates.pck
Врата | 18 | 0
Врата | 18 | 1
Врата | 18 | 2
Врата | 18 | 3
Врата | 18 | 4
Maintype 20 (Специальные объекты создаваемые инструкцией create special object, распознаваемые бортовым компьютером) файл типов TSpecial.pck
Кольцо Кесслера | 20 | 0
Кольцо Кесслера | 20 | 1
Неизвестный объект | 20 | 2
Астероид | 20 | 3
Астероид | 20 | 4
Неизвестный объект | 20 | 5
Неизвестный объект | 20 | 6
Неизвестный объект | 20 | 7
Неизвестный объект | 20 | 8
Неизвестный объект | 20 | 9
Неизвестный объект | 20 | 10
Неизвестный объект | 20 | 11
Неизвестный объект | 20 | 12
Неизвестный объект | 20 | 13
Неизвестный объект | 20 | 14
Неизвестный объект | 20 | 15
Неизвестный объект | 20 | 16
Неизвестный объект | 20 | 17
Неизвестный объект | 20 | 18
Неизвестный объект | 20 | 19
 | 20 | 20
 | 20 | 21
 | 20 | 22
 | 20 | 23
 | 20 | 24
Обтекатель | 20 | 25
Обтекатель | 20 | 26
Врата | 20 | 27
Астероид | 20 | 28
 | 20 | 29
Обломки корабля | 20 | 30
 | 20 | 31
 | 20 | 32
 | 20 | 33
Маяк | 20 | 34
 | 20 | 35
 | 20 | 36
Неизвестный объект | 20 | 37
Обломки станции | 20 | 38
Обломки станции | 20 | 39
Обломки станции | 20 | 40
Обломки станции | 20 | 41
Обломки станции | 20 | 42
Обломки корабля | 20 | 43
Maintype 29
Благодатное местечко | 29 | 1


Голосовые симплы Х2

v Голосовые симплы .

Голосовые симплы – это элементы основного языкового файла имеющие голосовую озвучку или видео. Все голосовые симплы поделены на странице по тематике. В Х2 имеются следующие голосовые симплы:

v Имена секторов .

На странице 7 основного языкового файла, хранятся имена всех секторов в игровой галактике. ID состоит из номера 102YYXX, где XX координата сектора по оси Х, а YY соответственно по оси Y. на карте галактики. Исчисление начинается от Kingdom End (Конец Королевства) координаты 01;01. Все названия секторов проговариваются голосом бортового компьютера. Координаты условные, так как при работе с координатами секторов командами из раздела «Команды работы с галактикой» нумерация в координатной сетке начинается с нуля, т.е. Kingdom End (Конец Королевства) имеет координаты 00;00.

ID # | Sector | Сектор | ID # | Sector | Сектор
1020101 | Kingdom End | Конец Королевства | 1020614 | Circle Of Labour | Круг Труда
1020102 | Rolk's Drift | Стремление Ролка | 1020616 | Xenon Sector 472 | Ксенонский Сектор 472
1020103 | Queen's Space | Пространство Королевы | 1020617 | Thyn's Abyss | Бездна Тина
1020104 | Menelaus' Frontier | Граница Менелаус | 1020701 | Emperor Mines | Императорские Шахты
1020105 | Ceo's Buckzoid | Баксоид Цео | 1020702 | Paranid Prime | Паранид Прайм
1020106 | Teladi Gain | Доход Телади | 1020703 | Priest Rings | Кольца Священника
1020107 | Family Whi | Семья Ви | 1020704 | Priest's Pity | Жалость Священника
1020114 | The Vault | Убежище | 1020705 | Danna's Chance | Шанс Данны
1020117 | Unknown Sector | Неизвестный сектор | 1020706 | Nopileos' Memorial | Мемориал Нопилео
1020118 | Xenon Sector 534 | Ксенонский Сектор 534 | 1020707 | Hatikvah's Faith | Вера Хатикваха
1020120 | Xenon Sector 596 | Ксенонский Сектор 596 | 1020708 | Aladna Hill | Холм Аладны
1020201 | Three Worlds | Три Мира | 1020709 | Akeela's Beacon | Маяк Акилы
1020202 | Power Circle | Круг Силы | 1020712 | Scale Plate Green | Зеленая Чешуйка
1020203 | Antigone Memorial | Мемориал Антигона | 1020713 | Nyana's Hideout | Убежище Наяны
1020204 | Rolk's Fate | Судьба Ролка | 1020714 | Omicron Lyrae | Омикрон Лиры
1020205 | Profit Share | Доля Прибыли | 1020715 | Treasure Chest | Сундук Сокровищ
1020206 | Seizewell | Источник Власти | 1020716 | Black Hole Sun | Черное Солнце
1020207 | Family Zein | Семья Зейн | 1020802 | Empire's Edge | Окраина Империи
1020214 | Shareholder's Fortune | Фортуна Акционеров | 1020803 | Duke's Domain | Владения Герцога
1020215 | Mines Of Fortune | Шахты Богатства | 1020804 | Emperor's Ridge | Императорский Отрог
1020218 | Getsu Fune | Гетсу Фане | 1020808 | Light of Heart | Свет Сердца
1020219 | Menelaus' Paradise | Рай Менелаус | 1020811 | Eighteen Billion | Восемнадцать Миллиардов
1020220 | Xenon Sector 597 | Ксенонский Сектор 597 | 1020812 | Xenon Sector 347 | Ксенонский Сектор 347
1020301 | Cloudbase North West | Северо-Западное Облако | 1020816 | Nathan's Voyage | Путешествие Натана
1020302 | Herron's Nebula | Туманность Неррона | 1020817 | Wastelands | Пустоши
1020303 | The Hole | Берлога (Штаб AMEC) | 1020818 | Unknown Sector | {7,1020000}
1020304 | Atreus' Clouds | Облака Атреус | 1020819 | Unknown Sector | {7,1020000}
1020305 | Spaceweed Drift | Наркотический Дрейф | 1020902 | Preacher's Void | Пустошь Проповедников
1020306 | Greater Profit | Больший Доход | 1020904 | Pontifex' Realm | Царство Понтифика
1020307 | Thuruk's Pride | Гордость Турука | 1020906 | Light Water | Легкая Вода
1020308 | Family Pride | Гордость Семей | 1020908 | Montalaar | Монталаар
1020310 | Patriarch's Retreat | Отступление Патриарха | 1020910 | New Income | Новый Доход
1020315 | Home Of Opportunity | Родина Возможности | 1020911 | Ianamus Zura | Ианамус Зура
1020319 | Bluish Snout | Посиневший Нос | 1020917 | Interworlds | Меж Миров
1020401 | Ringo Moon | Луна Ринго | 1021002 | Duke's Vision | Видение Герцогов
1020402 | Argon Prime | Аргон Прайм | 1021003 | Emperor's Wisdom | Мудрость Императоров
1020403 | The Wall | Стена (Штаб Обороны) | 1021004 | Trinity Sanctum | Святилище Троицы
1020404 | Farnham's Legend | Легенда Фарнхама | 1021005 | Preacher's Refuge | Приют Проповедника
1020405 | Bala Gi's Joy | Радость Бала Ги | 1021006 | Shore of Infinity | Берег Бесконечности
1020406 | Blue Profit | Постоянный Доход | 1021007 | Lucky Planets | Счастливые Планеты
1020407 | Rhonkar's Fire | Огонь Ронкара | 1021008 | Rolk's Legacy | Наследие Ролка
1020408 | Rhonkar's Clouds | Облака Ронкара | 1021009 | Great Trench | Великий Каньон
1020409 | Tharka's Sun | Солнце Тарка | 1021010 | Ceo's Doubt | Сомнение Цео
1020410 | Cho's Defeat | Поражение Чо | 1021104 | Bad Debt | Тяжелый Долг
1020415 | Family Tkr | Семья Ткр | 1021110 | LooManckStrat's Legacy | Наследие ЛуМанчкСтрата
1020416 | Tkr's Deprivation | Лишение Ткр | 1021202 | Unknown Sector | {7,1020000}
1020417 | Ghinn's Escape | Побег Гинн | 1021203 | Rhy's Desire | Желание Рай
1020418 | Hila's Joy | Радость Хила | 1021204 | Ministry Of Finance | Министерство Финансов
1020419 | Ocean of Fantasy | Океан Фантазии | 1021210 | Mi Ton's Refuge | Убежище Ми Тона
1020501 | Red Light | Красный Свет | 1021215 | Unknown Enemy Sector | Неизвест. Вражеский Сектор
1020502 | Home of Light | Дом Света | 1021217 | Unknown Enemy Sector | Неизвест. Вражеский Сектор
1020503 | President's End | Президентский Рубеж | 1021303 | Family Rhy | Семья Рай
1020504 | Elena's Fortune | Фортуна Елены | 1021310 | Moo-Kye's Revenge | Месть Ру-Кая
1020505 | Olmancketslat's Treaty | Договор Олманкетслата | 1021316 | Unknown Enemy Sector | Неизвест. Вражеский Сектор
1020506 | Ceo's Sprite | Дух Цео | 1021401 | Depths Of Silence | Глубина Молчания
1020507 | Family Rhonkar | Семья Чин | 1021402 | Dark Waters | Темной Воды
1020510 | Patriarch's Keep | Цитадель Патриарха | 1021403 | Reservoir Of Tranquillity | Запас Спокойствия
1020511 | Two Grand | Дважды Великий | 1021404 | Barren Shores | Пустынные Берега
1020517 | Family Njy | Семья Ню | 1021409 | Priest Refuge | Убежище Священника
1020518 | Njy's Deception | Обман Ню | 1021410 | Cardinal's Domain | Владение Кардиналов
1020519 | Family Ryk | Семья Райк | 1021411 | Sacred Relic | Священная Реликвия
1020601 | Cloudbase South West | Юго-Западное Облако | 1021415 | Unknown Enemy Sector | Неизвест Вражеский Сектор
1020602 | Ore Belt | Пояс Руды | 1021417 | Unknown Enemy Sector | Неизвест Вражеский Сектор
1020603 | Cloudbase South East | Юго-Восточное Облако | 1021503 | Great Reef | Великий Риф
1020604 | Split Fire | Сплитский Огонь | 1021509 | Spring Of Belief | Источник Веры
1020605 | Brennan's Triumph | Триумф Бреннана | 1021510 | Friar's Retreat | Отступление Фриара
1020606 | Company Pride | Гордость Компании | 1021511 | Pontifex' Seclusion | Уединение Понтифика
1020607 | Thuruk's Beard | Борода Турука |  |  |
1020611 | Profit Center Alpha | Центр Дохода Альфа |  |  |
1020612 | PTNI Headquarters | Штаб PTNI |  |  |

* перевод названий от версии Новый Диск

v Латинские и греческие буквы (page 9 & 12) .

На страницах 9 и 12 содержаться символы латинского и греческого алфавитов произносимые голосом компьютера

Page 9 Латинский алфавит |  | Page 12 Греческий алфавит
ID # | Литера | ID # | Литера
500 | A | 100 | alpha | альфа
501 | B | 101 | beta | бета
502 | C | 102 | gamma | гамма
503 | D | 103 | delta | дельта
504 | E | 104 | epsilon | эпсилон
505 | F | 105 | zeta | дзета
506 | G | 106 | eta | эта
507 | H | 107 | theta | тэта
508 | I | 108 | iota | йота
509 | J | 109 | kappa | каппа
510 | K | 110 | lambda | лямбда
511 | L | 111 | mu | мю
512 | M | 112 | nu | ню
513 | N | 113 | xi | кси
514 | O | 114 | omicron | омикрон
515 | P | 115 | pi | пи
516 | Q | 116 | rho | ро
517 | R | 117 | sigma | сигма
518 | S | 118 | tau | тау
519 | T | 119 | upsilon | ипсилон
520 | U | 120 | phi | фи
521 | V | 121 | chi | хи
522 | W | 122 | psi | пси
523 | X | 123 | omega | омега
524 | Y | 124 | omega | омега
525 | Z |  |  |

v Фразы бортового компьютера (page 13) .

Эти фразы произносятся бортовым компьютером, здесь приведены их идентификаторы и описание. Описание взято из перевода версии от «Нового Диска»/

1 | Вход в систему:
2 | Автопилот не установлен!
3 | Автопилот поврежден!
4 | Цель отсутствует!
5 | катапультирован
6 | Нацеливание
9 | Станция для посадки не обнаружена!
10 | внимание: ракета
11 | внимание: мина
13 | Ракет нет
15 | в доке
17 | неопознанный объект
18 | разрушился
20 | Получено сообщение:
22 | столкновение с
23 | с
24 | отсутствует
25 | не имеется
27 | в наличии
29 | уничтожено
30 | повреждено
31 | (_none M5 dock at M6_)Этот корабль слишком велик, чтобы состыковаться с кораблем класса М6. Только корабли класса M5 могут стыковаться с М6.
32 | (_TK class too large for ship_)Этот груз слишком велик для вашего корабля.
33 | (_TK class too large for ship_)Контейнер слишком велик!
34 | Новый походный порядок
35 | Новый походный порядок
36 | Цель за пределами связи
37 | ( _monitor steering lost or remote map lost_)Связь потеряна
38 | Игра сохранена
39 | Не удалось сохранить игру
40 | Загрузка игры
41 | Вас повысили
42 | Это пиратская копия X2
43 | (Shift S without insurance)Сохранить игру возможно лишь внутри станций или при наличии страхового свидетельства.
44 | Получено новое задание
45 | Эта величина - количество переходных врат, которые ваш транспорт может миновать в поисках товара для его фабрики.
46 | Вы можете снимать средства со счета вашей фабрики или переводить их на счет. Деньги нужны фабрике для того, чтобы посылать корабли за необходимыми товарами.
47 | Вы можете или разрешить или запретить кораблям других рас покупать ваши товары.
48 | Вы можете запрограммировать частоту, с которой ваш бортовой компьютер будет использовать ракеты.
49 | Вы можете установить походный порядок для корабля в том случае, если он является частью группы.
50 | Чтобы корабль мог выполнять сложные команды, вам нужно установить место, где он будет базироваться.
51 | Вы можете изменить в бортовом компьютере установки "свой-чужой".
52 | Для вашего бортового компьютера вы можете сохранить общие установки "свой-чужой". Общие установки те, которые применяются по умолчанию.
53 | Здесь вы сможете писать сложные программы для бортового компьютера своего корабля.
130 | Установите режим удаленного управления
131 | Команда принята
132 | Новая команда
133 | Новая удаленная команда не может быть выполнена
134 | Эта ракета не совместима с вашим кораблем
135 | Команда отклонена
136 | Это оружие не совместимо с вашим кораблем
137 | Этот щит не совместим с вашим кораблем
200 | выбран
1200 | Вы не сможете купить фабрику сейчас, потому что вы не имеете необходимого пространства, чтобы перевезти все оборудование, включенное в этот комплект. Вам нужно найти и нанять TL транспорт!
1245 | Начата постройка фабрики в секторе:
1246 | Завершена постройка фабрики в секторе:
1247 | Ваша фабрика в секторе:
1248 | требует больше ресурсов для производства!
1250 | Нет места для дополнительных лазеров
1251 | Нет места для дополнительных щитов
1252 | Нет места для дополнительных ракет
1253 | Нет места в грузовом отсеке
1254 | Недостаточно средств!
1255 | Осторожно! Шлюзовой отсек открыт, щиты отключены!
1256 | Шлюзовой отсек закрыт.
1257 | Шлюзовой отсек сейчас содержит (continues at 1293)
1258 | Цель в зоне поражения!
1259 | Цель покинула зону поражения!
1261 | Автопилот настроен на
1262 | Корабль атакован
1263 | Автопилот отключен
1264 | Автопилот включен
1265 | Внимание! Энергия на исходе!
1266 | Опасность! Вход в атмосферу!
1267 | Информация отсутствует
1268 | Катапультирование
1269 | Турбо режим включен
1270 | Щиты на пределе
1271 | Предупреждение
1272 | продано
1273 | куплено
1274 | установлено
1275 | снято
1276 | Аварийный сигнал от
1277 | Требуется помощь
1278 | Нас сканирует
1279 | by
1280 | Корабль сканируется
1282 | Цель потеряна
1283 | Стыковка разрешена
1284 | Стыковка запрещена
1285 | Стыковка отменена
1286 | перевод произведен
1287 | Новая цена выбрана
1288 | Средства переведены
1289 | Ресурсы не продаются
1290 | Продукты не покупаются
1291 | Радар в сферическом режиме
1292 | Радар в плоском режиме
1293 | Шлюзовой отсек пуст
1294 | готово
1295 | Кредиты, переведенные на счет фабрики после продажи продуктов, можно переводить на ваш личный счет. И наоборот, средства с личного счета могут быть переведены на счет фабрики так, чтобы ваши транспорты могли покупать сырье.
1296 | Вы можете установить цену, по которой транспорты данной фабрики должны покупать сырье
1297 | Изменение данных установок возможно только после приобретения транспорта для работы с этой фабрикой.
1298 | Вы можете установить цену, по которой другие фабрики и их транспорты смогут покупать ваш продукт. Чем меньше ваша цена, тем охотнее другие фабрики будут покупать именно у вас.
1299 | Вы можете заказать транспорты для перевозки необходимого сырья на эту фабрику. Когда вы закажете один или больше транспортов с верфи, эти транспорты полетят на эту фабрику и начнут работу.
1300 | Транспорт заказан на верфи.
1301 | Вы не можете продать транспорты.
1302 | Транспорт удален.
1303 | Вы можете заказать истребители, которые помогут защитить вашу фабрику. Когда вы закажете один или больше истребителей с верфи, они полетят на вашу фабрику и станут защищать ее.
1304 | Истребитель заказан на верфи
1305 | Вы не можете продавать истребители
1306 | Истребитель удален
1307 | Цель зафиксирована
1308 | Цель
1310 | Не работает в ДЕМО.
1311 | Отсутствует в ДЕМО.
1312 | Это ДЕМО закончится через t минус одну минуту
1313 | Чит режим
1319 | Гиперпрыжковый двигатель заряжен на 10%...20...30...40...50%...60...70...80...90... Прыжок...
1320 | Щиты
1321 | Лазер
1322 | Корпус корабля
1323 | поврежден
1324 | {13,1322} {13,1323} Корпус корабля поврежден
1326 | {1} (Object on target: 1=Object name)
1327 | {1} {2} (Target with Greek letter: 1=Object name, 2=Greek letter)
1332 | Получение дополнительной информации для базы данных
1333 | Сообщение
1334 | от
1339 | Кредитов получено
1340 | нас приветствует
1341 | сканирование
1342 | Этот объект принадлежит вам
1350 | Проверка системы
1351 | Тревога. Корабельные системы дали сбой. Начата проверка.
1352 | работает
1353 | сломано
1354 | не работает
1355 | вышло из строя
1356 | не отвечает
1357 | работает неправильно
1358 | Обычный двигатель
1359 | Вооружение
1360 | {13,1276} {1} (Emergency signal from ...)
1361 | {13,1333} {13,1334} {1} (Incoming message from ...)
1362 | {13,1340} {13,1279} {1} (We are being hailed by ...)
1363 | {13,1278} {13,1279} {1} (We are scanned by ...)
1501 | Контакт с местной торговой сетью.
1502 | Успешно сел
5001 | Запись начата
5002 | Запись остановлена
901299 | Вы можете указать число ваших транспортов, которые должны работать на эту фабрику.
901302 | Транспорт, не получивший указаний, будет следовать за вами в ожидании команды.
901303 | Вы можете указать число ваших истребителей, которые должны защищать эту фабрику.
901306 | Истребитель, не получивший указаний, будет следовать за вами в ожидании команды.
1100003 | Внимание, опасность столкновения!
1100014 | Бортовой компьютер ожидает новую команду
1100015 | Новая команда принята
1100016 | Принято
1100017 | Новая база назначена
1100018 | Внимание: атакуется одна из ваших фабрик
1100019 | Внимание: атакуется один из ваших кораблей
1100020 | Внимание: на одной из ваших фабрик остановлено производство. Проверьте наличие на ней ресурсов и средств.
1100025 | Внимание: игра не может произвести проверку оригинального CD при запуске. Пожалуйста, убедитесь, что вы используете правильный компакт-диск и перезапустите игру.
1100026 | Система самоуничтожения активирована.
1100027 | Внимание: обнаружено изменение исполняемого файла
1100039 | Станция слишком далеко
1100040 | Цель вне зоны действия. Телепортация невозможна.
1100041 | Цель вам не принадлежит. Телепортация невозможна.
1100042 | Нет ведомых
1100043 | Других ваших кораблей в этом секторе сейчас нет
1100044 | Новая команда: (follwed by 11001xx)
1100045 | Автономные дроны отсутствуют
1100046 | Мины отсутствуют
1100047 | Внимание, обнаружена мина
1100048 | Фабрике не хватает денег для покупки ресурсов
1100049 | Запрошенный товар не может быть куплен дешевле текущего порога цен.
1100056 | Гиперпрыжок отменен - Недостаточно энергии
1100065 | Добро пожаловать на борт

v Названия фабрик, кораблей, объектов (page 17)

В этом разделе собраны данные находящиеся на странице 17 основного языкового файла включающие в себя названия фабрик, кораблей и объектов. Все эти названия могут быть произнесены голосом бортового компьютера.

Фабрики и станции:

ID # | Станция | ID # | Станция | ID # | Станция
2011 | Solar Power Plant Солнечная электростанция | 2681 | Beta HEPT Forge Завод плазменных пушек BHEPT | 4281 | Royal Boron Dry-dock Боронский сухой док
2021 | Ore Mine Рудная шахта | 2691 | Gamma HEPT Forge Завод плазменных пушек GHEPT | 4381 | Split Dockyard Сплитская малая верфь
2031 | Silicon Mine Кремниевая шахта | 2711 | Shield Prod. Facility 1MW Завод щитов 1MW | 4481 | Paranid Pier Пирс империи Паранид
2041 | Weapon Component Factory Оружейный завод | 2721 | Shield Prod. Facility 5MW Завод щитов 5MW | 4581 | Teladi Showroom Теладианская выставка-распродажа
2051 | Crystal Fab Фабрика кристаллов | 2731 | Shield Prod. Facility 25MW Завод щитов 25MW | 4621 | Ion Disruptor Forge Завод Ионных деструкторов
2061 | Quantum Tube Fab Фабрика квантовых трубок | 2741 | Shield Prod. Facility 125MW Завод щитов 125MW | 4631 | Mobile Drilling System Factory Фабрика корабельных буров
2071 | Chip plant Фабрика микросхем | 2811 | Mosquito Missile Factory Завод ракет Москит | 4671 | Alpha PSG Forge Завод вихревых пушек APSG
2081 | Computer Plant Компьютерный завод | 2821 | Wasp Missile Factory Завод ракет Оса | 4681 | Beta PSG Forge Завод вихревых пушек BPSG
2141 | Wheat Farm Пшеничная фабрика | 2831 | Dragonfly Missile Factory Завод ракет Стрекоза | 4691 | Gamma PSG Forge Завод вихревых пушек GPSG
2151 | Cattle Ranch Аргонское ранчо | 2841 | Silkworm Missile Factory Завод ракет Шелкопряд | 4811 | Advanced Satellite Factory Фабрика улучшенных навигационных спутников
2171 | Rimes Fact Фабрика раймс | 2851 | Hornet Missile Factory Завод ракет Шершень | 4871 | Alpha PPC Forge Завод мезонных орудий APPC
2181 | Cahoona Bakery Кахунопекарня | 3101 | Federal Argon Shipyard Аргонская верфь | 4881 | Beta PPC Forge Завод мезонных орудий BPPC
2191 | Space Fuel Distillery Перегонный завод | 3181 | Free Argon Trading Station Аргонская торговая станция | 4891 | Gamma PPC Forge Завод мезонных орудий GPPC
2241 | Plankton Farm Ферма планктона | 3191 | Argon Equipment Dock Аргонский док оборудования | 4901 | Khaak missile forge – Sting Завод ракет хааков - Жало
2251 | Bio Gas Factory Фабрика биогаза | 3201 | Royal Boron Shipyard Королевская верфь Боронов | 4911 | Khaak missile forge – Needle Завод ракет хааков - Игла
2271 | Stott Mixery Стотт Фабрика | 3281 | Royal Boron Trading Station Королевская торговая станция | 4921 | Khaak missile forge Thorn Завод ракет хааков - Колючка
2281 | BoFu Chemical Lab Лаборатория БоФу | 3291 | Boron Equipment Dock Боронский док оборудования | 4941 | Lasertower Weapon Forge Завод орудий для лазерных башен
2341 | Scruffin Farm Ферма скруффинов | 3301 | Split Shipyard Верфь Сплитов | 4951 | Mass Driver Forge Завод автоматических пушек
2351 | Chelt Space Aquarium Челт-аквариум | 3381 | Split Trading Port Торговый порт Сплитов | 4961 | Ammunition Factory Завод камулятивных боеприпасов
2371 | Massom Mill Мельница массома | 3391 | Split Equipment Dock Сплитский док оборудования | 4971 | TerraCorp Headquarters Штаб-квартира ТерраКорп
2381 | Rastar Refinery Растарный завод | 3401 | Paranid Shipyard Паранидская верфь | 4981 | TerraCorp Crystal Fab Фабрика кристаллов ТерраКорп
2441 | Soyfarm Соевая ферма | 3481 | Paranid Trading Dock Паранидский торговый док | 4991 | TerraCorp Computer Plant Завод компьютерных плат ТерраКорп
2451 | Snail Ranch Улиточное ранчо | 3491 | Paranid Equipment Dock Паранидский док оборудования | 5001 | TerraCorp Solar Power Plant Солнечная электростанция ТерраКорп
2471 | Space Jewellery Ювелирный завод | 3501 | Teladi Shipyard Теладианская верфь | 5011 | TerraCorp Wheat Farm Пшеничная ферма ТерраКорп
2481 | Soyery Соевая фабрика | 3581 | Teladi Trading Station Теладианская торговая станция | 5021 | TerraCorp Cattle Ranch Ранчо ТерраКорп
2541 | Flower Farm Цветочная ферма | 3591 | Teladi Space Equipment Dock Теладианский космический док | 5031 | TerraCorp 125MW Shield Prod. Facility Фабрика 125MW щитов ТерраКорп
2551 | Teladianium foundry Теладианиумный завод | 3681 | Xenon Shipyard Верфь Ксенонов | 5041 | TerraCorp Quantum Tube Fab Завод квантовых трубок ТерраКорп
2561 | Dream farm Фабрика снов | 3691 | Xenon Station Станция Ксенонов | 5061 | Federal Argon Installation Пост федерации Аргон
2571 | Sun oil refinery Фабрика настропового масла | 3741 | Goner Temple Храм Гонеров | 5071 | Royal Boron Research Station Королевская исследовательская станция
2581 | Bliss Place Благодатное местечко | 3761 | Pirate Anarchy Port Пиратский анархический порт | 5081 | Paranid Communications Facility Паранидская станция связи
2611 | Alpha IRE Forge Завод импульсных пушек AIRE | 3781 | Pirate Base Пиратская база | 5111 | Argon Merchant Scrapyard Аргонская торговая верфь
2621 | Beta IRE Forge Завод импульсных пушек BIRE | 3891 | Satellite Factory Фабрика навигационных спутников | 5121 | Boron Ship Reclamation Yard Королевская восстановительная верфь
2631 | Gamma IRE Forge Завод импульсных пушек GIRE | 3911 | SQUASH Mine Factory Фабрика мин СКВОШ | 5131 | Split Scrap Merchants Сплитские торговцы металлоломом
2641 | Alpha PAC Forge Завод фотонных пушек APAC | 3921 | Lasertower Factory Фабрика лазерных башен | 5141 | Paranid Salvage Merchants Паранидские торговцы вторсырьем
2651 | Beta PAC Forge Завод фотонных пушек BPAC | 3931 | Drone Factory Фабрика Дронов | 5151 | Teladi Company Scrap Dealers Торговцы ломом Теладианской компании
2661 | Gamma PAC Forge Завод фотонных пушек GPAC | 4181 | Federal Argon Wharf Причал федерации Аргон | 9021 | Unknown Enemy Station Неизвестная вражеская станция
2671 | Alpha HEPT Forge Завод плазменных пушек AHEPT |  |  |  |

Товары и апгрейды

ID# | Товар | ID# | Товар | ID# | Товар
2013 | Батареи (Energy Cells) | 2633 | Импульсная пушка гамма (Gamma IRE) | 4893 | Фотонная пушка гамма (Gamma PPC)
2023 | Руда (Ore) | 2643 | Ускоритель альфа (Alpha PAC) | 4903 | Ракета Жало (Sting)
2033 | Кремниевые пластины (Silicon Wafers) | 2653 | Ускоритель бета (Beta PAC) | 4913 | Ракета Игла (Needle)
2043 | Боеголовки (Warheads) | 2663 | Ускоритель гамма (Gamma PAC) | 4923 | Ракета Колючка (Thorn)
2053 | Кристаллы (Crystals) | 2673 | Плазменная пушка альфа (Alpha HEPT) | 4943 | Орудия для лазерных башен (Lasertower Weapon)
2063 | Квантовые трубки (Quantum Tubes) | 2683 | Плазменная пушка бета (Beta HEPT) | 4953 | Пушка MD (Mass Driver)
2073 | Микросхемы (Microchips) | 2693 | Плазменная пушка гамма (Gamma HEPT) | 4963 | Камулятивные боеприпасы (Mass Driver Ammunition)
2083 | Компьютерные платы (Computer Components) | 2713 | Щит 1 МВт (1 MW Shield) | 5203 | Артефикаты (Artifacts)
2093 | Страховка (Salvage Insurance) | 2723 | Щит 5 МВт (5 MW Shield) | 5213 | Удобрения (Artificial Fertilizer)
2103 | Аргонская полицейская лицензия (Argon law enforcement license) | 2733 | Щит 25 МВт (25 MW Shield) | 5223 | Микроорганизмы (Biological Micro-Organisms)
2133 | Форсаж двигателя (Engine Tuning) | 2743 | Щит 125 МВт (125 MW Shield) | 5233 | Картографические чипы (Cartography Chips)
2143 | Отборная пшеница (Delexian Wheat) | 2753 | Сканер минералов (Mineral Scanner) | 5243 | Детали оборудования (Construction Equipment)
2153 | Мясо аргну (Argnu beef) | 2763 | Сканер грузов (Freight scanner) | 5253 | Компоненты двигателя (Engine Components)
2163 | Проектор эклиптики (Ecliptic projector) | 2773 | Расширенная торговая система (Trading system extension) | 5263 | Чипы развлечений (Entertainment Chips)
2173 | Ткань раймс (Cloth Rimes) | 2813 | Ракета "Москит" (Mosquito Missile) | 5273 | Пища (Food Rations)
2183 | Бифштексы кахуна (Meatsteak Cahoonas) | 2823 | Ракета "Оса" (Wasp Missile) | 5283 | Ручное оружие (Hand Weapons)
2193 | Космическое топливо (Space Fuel) | 2833 | Ракета "Стрекоза" (Dragonfly Missile) | 5293 | Деликатесы (Luxury Foodstuffs)
2203 | Боронская полицейская лицензия (Boron law enforcement license) | 2843 | Ракета "Шелкопряд" (Silkworm Missile) | 5303 | Медецинское оборудование (Medical Equipment)
2213 | Система анализа движения (Motion Analysis Relay System) | 2853 | Ракета "Шершень" (Hornet Missile) | 5313 | Mining Equipment
2243 | Планктон (Plankton) | 2923 | Baluga missile | 5323 | Нивидиум (Nividium)
2253 | Биогаз (BoGas) | 2933 | Alpha missile | 5333 | Радиоактивные отходы (Radioactive Waste)
2263 | SETA boost extension | 3883 | Пленники (Slaves) | 5343 | Теладиумные панели (Teladianium Panelling)
2273 | Специи Стотт (Stott Spices) | 3893 | Навигационный спутник (Navigation Relay Satellite) | 5353 | Вода (Water)
2283 | БоФу (BoFu) | 3903 | Анализатор цен продажи (Best Selling Price Locator) | 5363 | Оружейные чипы (Weapon Interface Chips)
2303 | Полицейская лицензия сплитов (Split police license) | 3913 | Мина СКВОШ (SQUASH Mine) | 5373 | Наркотики (Narcotics)
2313 | Сингулярный уплотнитель времени (Singularity Engine Time Accelerator) | 3923 | Лазерная башня (Lasertower) | 5383 | Super Slave Chips
2343 | Фрукты Скруффин (Scruffin Fruits) | 3933 | Боевой дрон (Fighter Drone) | 5393 | Яйца космомух (Spacefly Eggs)
2353 | Мясо челтов (Chelts Meat) | 3943 | Cargo Life Support System | 5403 | Ручное оружие пиратов (Pirate Sidearms)
2373 | Порошок Массом (Massom powder) | 3953 | Расширение (Boost Extension) | 5413 | Хакерские чипы (Hackerchips)
2383 | Растарное масло (Rastar Oil) | 3963 | Боковые двигатели (Strafe Drive Extension) | 5423 | Military Personnel
2393 | Космомуха (Spaceflies) | 3973 | Телепорт (Transporter Device) | 5433 | Пассажир (Passengers)
2403 | Паранидская полицейская лицензия (Paranid police license) | 3983 | Джампдрайв (Jumpdrive) | 5443 | Очень важный пассажир (Very Important Passengers)
2413 | Стыковочный компьютер (Docking computer) | 3993 | Анализатор цен покупки (Best Buys Locator) | 5453 | Сканер МК2 (Duplex Scanner)
2423 | Видеоочки (Video Enhancement Goggles) | 4623 | Ионный диструктор (Ion Disruptor) | 5463 | Сканер МК3 (Triplex Scanner)
2443 | Соевые бобы (Soja Beans) | 4633 | Мобильная бурвая установка (Mobile Drilling System) | 5543 | TRACKER Mine (Мина следопыт)
2453 | Улитки Майа (Maja Snails) | 4643 | Кионный эмиттер Альфа (Alpha Kyon Emitter) | 5603 | Красный кристалл (Red Crystal)
2463 | Оптимизация рулевого управления (Rudder Optimisation) | 4653 | Кионный эмиттер Бета (Beta Kyon Emitter) | 5623 | Зеленый кристалл (Green Crystal)
2473 | Маяглит (Majaglit) | 4663 | Кионный эмиттер Гамма (Gamma Kyon Emitter) | 5633 | Желтый ристал (Yellow Crystal)
2483 | Соевая мука (Soja Husk) | 4673 | Силовая пушка альфа (Alpha PSG) | 5643 | Прозрачный кристалл (Transparent Crystal)
2503 | Лицензия теладианской службы охраны (Teladi company security license) | 4683 | Силовая пушка бета (Beta PSG) | 5653 | Черный кристалл (Black Crystal)
2513 | Расширение грузового отсека (Cargo bay extension) | 4693 | Силовая пушка гамма (Gamma PSG) | 5663 | Цветной кристалл (Glowing Crystal)
2543 | Солнечные цветы (Sunrise Flowers) | 4803 | Камера дрона (Camera Drone) | 5673 | Навигационный софт (Navigation Command Software MK1)
2553 | Теладианиум (Teladianium) | 4813 | Улучшенный спутник (Advanced Satellite) | 5683 | Торговый софт МК1 (Trade Command Software MK1)
2563 | Болотная трава (Swamp Plant) | 4823 | Сборщик руды (Ore Collector) | 5693 | Торговый софт МК2 (Trade Command Software MK2)
2573 | Ностроповое масло (Nostrop Oil) | 4833 | Маскировочное устройство (Camouflage Device) | 5713 | Боевой софт МК1 (Fight Command Software MK1)
2583 | Космотабак (Space weed) | 4863 | Ловушка для космомух (Spacefly Collector) | 5723 | Боевой софт МК2 (Fight Command Software MK2)
2613 | Импульсная пушка альфа (Alpha IRE) | 4873 | Фотонная пушка альфа (Alpha PPC) | 5733 | Спец.софт (Special Command Software MK1)
2623 | Импульсная пушка бета (Beta IRE) | 4883 | Фотонная пушка бета (Beta PPC) | 5873 | Торговый софт МК3 (Trade Command Software MK3)

Корабли:

ID | Корабль | ID | Корабль
3111 | Argon Colossus (Аргонский колосс) | 4011 | Khaak Carrier (Хаакский носитель)
3121 | Argon Titan (Аргонский Титан) | 4021 | Khaak Destroyer (Хаакский Разрушитель)
3141 | Argon Buster (Аргонский Бастер) | 4031 | Khaak Fighter (Хаакский истребитель)
3151 | Argon Discoverer (Аргонский Первооткрыватель) | 4041 | Khaak Interceptor (Хаакский перехватчик)
3161 | Argon Mammoth (Аргонский Мамонт) | 4051 | Khaak Scout (Хаакский разведчик)
3211 | Boron Shark (Боронская Акула) | 4061 | Khaak Cluster (Хаакский кластер)
3221 | Boron Ray (Боронский Скат) | 4081 | Khaak Station (Хаакская Станция)
3251 | Boron Octopus (Боронский Осьминог) | 4111 | Argon Centaur (Аргонский Кентавр)
3261 | Boron Orca (Боронская Касатка) | 4131 | Argon Nova (Аргонская Нова)
3271 | Boron Dolphin (Боронский Дельфин) | 4161 | Argon Express (Аргонский Экспресс)
3311 | Split Raptor (Сплитский Хищник) | 4171 | Argon Mercury (Аргонский Меркурий)
3321 | Split Python (Сплитский Питон) | 4211 | Boron Hydra (Боронская Гидра)
3331 | Split Mamba (Сплитская Мамба) | 4231 | Boron Barracuda (Боронская Баракуда)
3341 | Split Scorpion (Сплитский Скорпион) | 4241 | Boron Mako (Боронский Мако)
3361 | Split Elephant (Сплитский Слон) | 4261 | Boron Manta (Боронская Манта)
3411 | Paranid Zeus (Паранидский Зевс) | 4311 | Split Dragon (Сплитский Дракон)
3421 | Paranid Odysseus (Паранидский Одиссей) | 4351 | Split Jaguar (Сплитский Ягуар)
3451 | Paranid Pegasus (Паранидский Пегас) | 4361 | Split Iguana (Сплитская Игуана)
3461 | Paranid Hercules (Паранидский Геркулес) | 4371 | Split Caiman (Сплитский Крокодил)
3471 | Paranid Ganymede (Паранидский Ганимед) | 4411 | Paranid Nemesis (Паранидский Немезис)
3511 | Teladi Condor (Теладианский Кондор) | 4441 | Paranid Pericles (Паранидский Перикл)
3521 | Teladi Phoenix (Теладианский Феникс) | 4461 | Paranid Hermes (Паранидский Гермес)
3531 | Teladi Falcon (Теладианский Фалкон) | 4471 | Paranid Demeter (Паранидская Деметра)
3561 | Teladi Albatross (Теладианский Альбатрос) | 4511 | Teladi Osprey (Теладианский Оспрей)
3571 | Teladi Vulture (Теладианский Гриф) | 4541 | Teladi Buzzard (Теладианский Бузард)
3611 | Xenon J | 4551 | Teladi Harrier (Теладианский Хариер)
3621 | Xenon K | 4561 | Teladi Toucan (Теладианский Тукан)
3631 | Xenon L | 4731 | Xperimental Shuttle (Эксперементальный шатл)
3641 | Xenon M | 4741 | Space Suit (Космический скафандр)
3651 | Xenon N | 4751 | Goner Ship (Корабль Гонеров)
3661 | Xenon I | 4771 | Camera Drone (Разведывательный дрон)
3671 | Xenon H | 4931 | Paranid Perseus (Паранидский Персей)
3771 | Pirate Ship (Пиратский корабль) | 5051 | Navigational Beacon (Навигационный маяк)
3811 | Pirate Orinoco (Пиратский Ориноко) | 5091 | Argon One (Аргонец)
3821 | Pirate Bayamon (Пиратский Байямонд) | 5501 | Saiien II (Сайен 2)
3831 | Pirate Mandalay (Пиратский Минделай) | 5511 | Nikkonofune (Никконофун)
3841 | Navigation Relay Satellite (Навиг. Спутник) | 5521 | Blue Arrow (Голубая стрела)
3851 | SQUASH Mine (Мина СКВОШ) | 5543 | TRACKER Mine (мина Следопыт)
3861 | Lasertower (Лазерная башня) | 5581 | Pyramid Income (Высокий доход)
3871 | Fighter drone (Боевой дрон) | 5591 | Saiien III (Сайен 3)


00.jpg

Тип 00 Размер: 50000 (225м)


01.jpg

Тип 01 Размер: 40000 (180м)


02.jpg

Тип 02 Размер: 200000 (900м)


03.jpg

Тип 03 Размер: 3100 (14м)


04.jpg

Тип 04 Размер: 200000 (900м)


05.jpg

Тип 05 Размер: 12000 (54м)


06.jpg

Тип 06 Размер: 1000000 (4,5км)


07.jpg

Тип 07 Размер: 32400 (146м)


08.jpg

Тип 08 Размер: 47400 (213м)


09.jpg

Тип 09 Размер 64900 (292м)


Thumbnails

Типы астероидов

Здесь приведены все типы астероидов имеющихся в Х2. Тип, соответствует параметру <type> вводимому для инструкции create asteroid. Размер указан в юнитах, для перевода его в метры разделите значение на 222. Сам размер подразумевает под собой, радиус предполагаемой сферы врутрь которой заключен объект (получен инструкцией get size object).

Для увеличения скрина кликните на миникартинке.

Тип 00 Размер: 50000 (225м) | Тип 01 Размер: 40000 (180м) | Тип 02 Размер: 200000 (900м)
Тип 03 Размер: 3100 (14м) | Тип 04 Размер: 200000 (900м) | Тип 05 Размер: 12000 (54м)
Тип 06 Размер: 1000000 (4,5км) | Тип 07 Размер: 32400 (146м) | Тип 08 Размер: 47400 (213м)
Тип 09 Размер 64900 (292м) |  |

Кликните на картинке для просмотра полного изображения.


Thumbnails

Визуальные образы пилотов

Здесь собраны визуальные образы пилотов и их коды. Код указывается в параметре face команды set pilot speaker. Для основных рас имеется по пять образов, плюс два пиратских образа для представителей этой расы. Для расы Аргон предусмотрено больше образов. В таблице под картинкой указан код образа:

раса: Аргон код:101 | раса: Аргон код:102 | раса: Аргон код:103
раса: Аргон код:104 | раса: Аргон код:105 | раса: Аргон код:106
раса: Аргон код:107 | раса: Аргон код:108 | Елено Хо код:120
Сая Хо код:121 | Брет код:122 | Бен Данна код:158
раса: Борон код:201 | раса: Борон код:202 | раса: Борон код:203
раса: Борон код:204 | раса: Борон код:205 | раса: Сплиты код:301
раса: Сплиты код:302 | раса: Сплиты код:303 | раса: Сплиты код:304
раса: Сплиты код:305 | раса: Параниды код:401 | раса: Параниды код:402
раса: Параниды код:403 | раса: Параниды код:404 | раса: Параниды код:405
раса: Телади код:501 | раса: Телади код:502 | раса: Телади код:503
раса: Телади код:504 | раса: Телади код:505 | раса: Пираты код:811
раса: Пираты код:812 | раса: Пираты код:813 | раса: Пираты код:821
раса: Пираты код:822 | раса: Пираты код:831 | раса: Пираты код:832
раса: Пираты код:841 | раса: Пираты код:842 | раса: Пираты код:851
раса: Пираты код:852 | раса: Гонеры код:901 | раса: Гонеры код:902
раса: Ксеноны код:903 |  |


00.jpg

Next Page

Click the image to return to the thumbnails.


01.jpg

Тип: 01

Click the image to return to the thumbnails.


02.jpg

Тип: 02

Click the image to return to the thumbnails.


03.jpg

Тип: 03

Click the image to return to the thumbnails.


04.jpg

Тип: 04

Click the image to return to the thumbnails.


05.jpg

Тип: 05

Click the image to return to the thumbnails.


06.jpg

Тип: 06

Click the image to return to the thumbnails.


07.jpg

Тип: 07

Click the image to return to the thumbnails.


08.jpg

Тип: 08

Click the image to return to the thumbnails.


09.jpg

Тип: 09

Click the image to return to the thumbnails.


10.jpg

Тип: 10

Click the image to return to the thumbnails.


11.jpg

Тип: 11

Click the image to return to the thumbnails.


12.jpg

Тип: 12

Previous Page

Click the image to return to the thumbnails.


Thumbnails

Типы туманностей

В Х2 имеется 13 типов туманностей. Тип указывается в параметре <type> команды create nebula и указывает на визуальную 3D-модель туманности.

Тип: 00 | Тип: 01 | Тип: 02
Удлиненное облако белого газа, периодически пронзаемое вспышками молний. | Небольшое облако красного газа. | Удлиненное облако белого газа.
Тип: 03 | Тип: 04 | Тип: 05
Туманность состоит из нескольких облаков красного газа, с периодическими вспышками молний. | Два облака белого газа. | Несколько облаков белого и синего цветов с периодическими вспышками молний
Тип: 06 | Тип: 07 | Тип: 08
Белые вихри из красного облака. | Огромное облако пурпурного газа, со вспышками молний. | Большие белые вихри исходящие из красного облака, со вспышками молний.
Тип: 09 | Тип: 10 | Тип: 11
Удлиненные облака ярко-синего газа | Болшая туманность из сине-зеленого газа, со вспышками молний. | Два сине-зеленых облака, со вспышками молний.
Тип: 12 |  |
Небольшая красная туманность, со вспышками молний.

Кликните на картинке для просмотра большого изображения.


Навигационные команды

Специальные объекты с 0 по 14

Оглавление Сообщение об ошибках Ваше мнение о проекте E-Mail автору


Навигационные команды

Специальные объекты с 15 по 32

Оглавление Сообщение об ошибках Ваше мнение о проекте E-Mail автору


Навигационные команды

Специальные объекты с 33 по 49

Оглавление Сообщение об ошибках Ваше мнение о проекте E-Mail автору


Навигационные команды

Специальные объекты с 50 по 73

Оглавление Сообщение об ошибках Ваше мнение о проекте E-Mail автору


Визуальный тип солнца: 00

Тип: 00
Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 01

Тип: 01
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 02

Тип: 02
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 03

Тип: 03
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 04

Тип: 04
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 05

Тип: 05
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 06

Тип: 06
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 07

Тип: 07
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 08

Тип: 08
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 09

Тип: 09
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 10

Тип: 10
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 11

Тип: 11
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 12

Тип: 12
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 13

Тип: 13
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 14

Тип: 14
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 15

Тип: 15
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 16

Тип: 16
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 17

Тип: 17
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 18

Тип: 18
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 19

Тип: 19
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 20

Тип: 20
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 21

Тип: 21
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 22

Тип: 22
Предыдущуй тип | Следующий тип

Кликните на изображении для возврата.


Визуальный тип солнца: 23

Тип: 23
Предыдущуй тип

Кликните на изображении для возврата.


Визуальные модели типов солнц.

Описание типов солнц

Тип: 00 | Тип: 01 | Тип: 02
Тип: 03 | Тип: 04 | Тип: 05
Тип: 06 | Тип: 07 | Тип: 08
Тип: 09 | Тип: 10 | Тип: 11
Тип: 12 | Тип: 13 | Тип: 14
Тип: 15 | Тип: 16 | Тип: 17
Тип: 18 | Тип: 19 | Тип: 20
Тип: 21 | Тип: 22 | Тип: 23

Кликните на изображении для просмотра большого изображения.


Аудио команды

v Аудио команды

play sample <samplnumber>

Проигрывает звуковой сэмплы с номером <samplnumber>. Сэмплы хранятся в папке "s" игры и имеют формат WAV. Номера сэмплов совпадают с именем файла. Это всякого рода простые звуки, например открытия люка, звук от выстрела и т.п. Описание стандартных сэмплов в приложении Сэмплы "X2 The Threat". Помимо этого существует возможность добавить собственные симплы, но к сожалению количество их ограниченно и ScE доступны далеко не все номера. Если вы желаете добавить собственный сэмпл то используйте для них следующие номера 7-21, 23-45, 50-52, 57-58, 65-69, 73-74, 78-83, 87-93. Теперь добавьте нужный вам звук (файл в формате WAV) в папку \s, и переименуйте его в соответствующую цифру. Например, для того чтобы ваш сэмпл воспроизводился командой play sample 21, ваш WAV файл должен быть назван 21.WAV и соответственно он должен находиться в папке \s из основной папки игры.

play sample: incoming transmission <transmissiontype> from object <source>

<transmissiontype> это константы типа IncomingMessage.XXXX. Работа команды заключается в произнесении голосом бортового компьютера фразы в зависимости от аргумента. Аргумент from object - по идее должен указывать источник сообщения, но в версии 1.4 эта функция не работает.

Для этой инструкции в ScE предусмотрено четыре специальных константы

Имя константы | Значение | Сообщение
[IncomingTransmission.Greeting] | 1362 | “Вас приветствует”
[IncomingTransmission.Message] | 1361 | “Поступило сообщение”
[IncomingTransmission.Scanned] | 1363 | “Нас сканируют”
[IncomingTransmission.SOS] | 1360 | “Аварийный сигнал от”

<object> send audio message <massagetype> to player

Игроку посылается аудио/видео сообщение от объекта <object>, объектом должен являться корабль. В качестве параметра <messagetype> используются константы Comm.XXXX. Видео изображение пилота от которого пришло сообщение формируется в зависимости от расы владельца <object>. Сообщение может поступить только от корабля находящегося в том же секторе что и игрок.

Имя константы | Значение | Сообщение
Comm.DLG_POL_ILLEGAL_GOODS | 75 | На борту обнаружен нелегальный груз.
Comm.DLG_POL_LAST_WARNING | 76 | Последнее предупреждение сбросьте нелегальный груз или открываем огонь
Comm.DLG_POL_LEGAL_GOODS | 77 | Ваш корабль просканирован, нелегальных грузов не обнаружено.
Comm.C_START_FIGHTING | 4 | Сообщение о начале атаки на ваш корабль игрока

send incoming message <message> display it=[TRUE]|[FALSE]

Посылает сообщение <message> игроку. Если display it=[TRUE], то сообщение сразу же отображается на экране, если [FALSE] - записывается в журнал, игрок получает уведомление "Пришло новое сообщение". Чтобы в поле "От:" было написано от кого пришло сообщение придется предварительно записать это сообщение в языковой файл ХХХХХХ.XML используя теги форматирования. Как пример приведу самое первое сообщение которое приходит от Бена Даны, в самом начале игры. Расположено это сообщение в 70001.XML pageID=108 textID=220701. Выглядит оно вот так:

[author]Бен Данна[/author][text colwidth='500'] Привет, Джулиан. Как мы уже говорили, я хочу, чтобы ты поработал курьером для "ТерраКорп". Встреться с вице-президентом [b]Еленой Хо[/b] в [b]штаб-квартире "ТерраКорп"[/b] в секторе [blue]Home of Light[/blue]. Поскольку непосредственная связь не всегда возможна, я буду посылать тебе текстовые сообщения наподобие этого, если произойд‘т что-нибудь важное. Удачи![/text]

Для демонстрации нужна небольшая программка:

001   $str = sprintf: pageid=108 textid=220701, null, null, null, null, null
 002   send incoming message $str to player: display it=[TRUE]
 003   return null

Так как 70001.XML грузится при старте игры, а обращаемся мы непосредственно к нему, то load text: id можно не использовать. Запускаем ее, сразу же получаем сообщение от Бена Даны. Текст между [b] … [/b] желтого цвета, а между [blue]…[/blue] голубой. [author]..от кого сообщение..[/author] должно стоять первым. Тэг [text colwidth='500'] … [/text] устанавливает ширину колонки, этот параметр должен заключать внутри себя весь текст сообщения вместе с другими тегами. Тэг [author] должен стоять первым так как он, не является частью сообщения (описание тэгов и спецсимволов в разделе «Языковые файлы - Использование тэгов и спецсимволов).

<RetVar/IF/START> speak text: page=<pagenum> id=<idnum> priority=<priority>

Команда воспроизводит голосовое сообщение. Работа команды схожа с командой play sample: incoming transmission , отличие заключается в том, что место нахождения сообщения указывается пользователем. Также эта команда может проиграть голосовой клип как команда send audio message, только не будет отражаться видео.

Текст сообщений храниться в файле 70001.xml на странице 13. Если играющий не отключил показ субтитров то, при воспроизведении голосового сообщения в нижней части экрана будут отражены субтитры (текст взятый с соответствующей страницы и идентификатора), соответственно субтитры будут на языке локализации. Если сообщение имеет связанный с ним аудио компонент, то он будет тоже проигран.

Использование команды возможно с префиксом START, который означает, что скрипт не будет ожидать конца текста, а продолжит выполнение. Если в момент озвучивания текста приходит запрос на воспроизведение голосового сообщения с таким же или большим приоритетом - озвучиваемый текст перебивается запросом. Если приоритет меньше - запрос игнорируется.

Все сообщения Х2 имеющие аудио/видео компонент, описаны в разделе «Приложение - Голосовые сэмплы».

Для данной команды имеется возможность составлять ценные фразы из отдельных симплов. Делается это при помощи языкового файла. На любую свободную страницу и идентификатор помещаются ссылки на строки состоящие из голосовых симплов, см. «Приложение - Голосовые сэмплы». Ссылки записываются заключенными в фигурные скобки вот пример такой записи:

  <?xml version="1.0" ?>

- <language id="7">

- <page id="1" title="" descr="">

  <t id="1236">{13,1350}{13,1274}</t>

  <t id="1237">{13,37}{13,135}</t>

  <t id="1238">{13,131}{13,1275}</t>

  </page>

  </language>

теперь соответственно если в скрипте записать строку :

speak text: page=1 id=1236 priority=0

то бортовой компьютер последовательно воспроизведет голосовые симплы с 13 страницы по ID 1350 {13,1350} и сразу же из ID 1274 с той же страницы {13,1274}. В нашем случае борт.компьютер произнесет «Проверка системы. Подключение произведено».


Общие команды

Команды ScE "X2 The Threat"

v Общие команды

NOP

Нет операции.

<RetVar/IF> <Expression>

Данная функция выполняет несколько задач:

1. Создать новую переменную и присвоит ей значение или присвоить уже имеющейся переменной <RetVar> результат выражения/функции/команды <Expression>.

Пример:

001 $NewVar = 5

002 $Total = 3+2

003 $Total2 = $NewVar+$Total

004 $string = ‘Hello World.”

или вернуть значение, логического типа, выражения/функции/команды <Expression> для обработки в операторе сравнения <IF>.

Пример:

001 if $NewVar => 6

…

040 if not $Total

…

057 skip if $Total2

и тому подобные интерпретации. Также значение <Expression> при помощи данной инструкции модно передать оператору While при организации циклов.

005 while $NewVar <7

…

020 end

inc<RetVar>=

Увеличивает значение <RetVar> на 1 (инкремент). Функция выполняет операцию идентичную <RetVar>=<RetVar> + 1

dec<RetVar>=

Уменьшает значение <RetVar> на 1 (декремент). Функция выполняет операцию идентичную <RetVar>=<RetVar> - 1

@<RetVar/IF> wait <Var/Number> ms

Ожидать <Var/Number> ms. Возвращает количество прошедших ms. <Var/Number> или информацию о том происходило ли прерывание за время ожидания <IF>. Показатель ms приблизительный. Так как минимальное время ожидания не может быть меньше времени прогонки одного фрейма, то есть чтобы вычислить минимальную задержку нужно взять текущее количество фреймов в секунду и рассчитать по формуле <мин.задержка>= 1000/<fps>, получим количество ms за один фрейм это будет минимальное время задержки. Например, если fps = 35 то самое минимальное время задержки будет не менее 28 ms.

@<RetVar/IF> wait randomly from <Var/Number> to <Var/Number> ms

Ожидать случайное число ms. в диапазоне от <Var/Number> до <Var/Number> ms. Возвращает количество прошедших ms., или информацию о том происходило ли прерывание за время ожидания <IF>.

<Var> = Random value from 0 to <maximum> -1

Сгенерировать и присвоить переменной <Var> случайное число в диапазоне от 0 до < maximum > -1. Эту инструкцию очень удобно использовать для выбора из массива случайного элемента, где <maximum> размерность массива.

<Var> = Random value from <minimum> to <maximum> -1

Сгенерировать и присвоить переменной <Var> случайную величину в диапазоне от <minimum> до <maximum> -1.

* <Comment>

Комментарий. Любой текст не интерпретируемый ScE. Используется для того чтобы в листинге НС дать объяснения чего либо или выделить. Отображается серым цветом, за символом *

<RetVar>= script engine version

Возвращает версию ScE в переменную <RetVar> после версии 1.4 "X2 The Threat" версии ScE от 25 и выше. При помощи этой функции легко сделать проверку исключающую запуск скрипта на движке версией ниже той для которой он был написан. Наличие таких проверок в самом начале ваших скриптов, обеспечит их правильную работу.

Пример:

001 $EngineVersion = script engine version

002 skip if $EngineVersion >= 25

003 return null

… дальнейший код скрипта рассчитанный на ScE версии не ниже 25…

<RetVar> = get script priority

Вернуть приоритет текущего скрипта (того скрипта который выполнил эту инструкцию). Эта команда будет очень полезной при организации сложных взаимодействий скриптов. Пример такого взаимодействия рассмотрен в главе «Сигналы» => Раздел «ScE»

set script priority to <priority>

Установить приоритет скрипта равным <priority>. Значение должно быть в пределах от 0 до 10000. По умолчанию приоритет любого скрипта запущенного командой call или из скриптового редактора равен 0.

<RetVar/IF>is script prio <prio> on stack

Возвращает [TRUE] если в текущем стеке находится (выполняется в данный момент или стоит в очереди на выполнение) скрипт с приоритетом <prio>. Т.е. если эта команда вызвана из скрипта, запущенного в стеке Task 10, то будут проанализированы все скрипты, включая текущий, но запущенные только в этом же стеке Task 10 этого же объекта. Кстати, весьма полезная команда. На сегодня это единственная команда, с помощью которой извне (из другого скрипта) можно узнать а запущен ли такой-то скрипт в таком-то слоте такого-то корабля/станции. Эта функция может быть использована для определения какой сигнал был получен кораблем и выполняемые в текущий момент действия. Определяя находится ли в стеке этого корабля скрипт обработчик сигнала. Например: если при проверке находится ли в стеке скрипт с приоритетом 99, инструкция возвращает [TRUE], то это означает, что корабль подвергся нападению и оказывает сопротивление нападающему. В таблице указаны приоритеты скриптов обработчиков, назначенные им по умолчанию.

Prio | Используется
0 | Все скрипты по умолчанию
50 | Бегство после обработки SIGNAL_ATTACKED
99 | Вооруженное сопративление после обработки SIGNAL_ATTACKED
100 | SIGNAL_ATTACKED
150 | SIGNAL_LEADERNEEDSHELP SIGNAL_FOLLOWERNEEDSHELP
200 | SIGNAL_FORMATIONLEADERCHANGED
300 | SIGNAL_CAPTURED
10000 | SIGNAL_KILLED

<RefObj> start task <Var/Number1> with script <Script Name> and prio <Var/Number2>: arg1=<Value1> arg2=<Value2> arg3=<Value3> arg4=<Value4> arg5=<Value5>

Запускает скрипт <Script Name> в стеке Task <Var/Number1> объекта <RefObj> с приоритетом <Var/Number2> и параметрами <Value1> ... <Value5>, при этом вытеснив (удалив) все остальные скрипты из этого же стека.

Внимание! Командой start task <Var/Number> with script ни в коем случае нельзя запускать скрипт в текущем стеке! (т.е. на том же объекте и том же Task, где запускается команда start task) Если это сделать, скрипт повиснет.

Этот команда может быть использована для запуска скриптов турелей (Task с 1 по 6), слот дополнительных корабельных команд (Task с 10 по 11), слот команды станций ( Task 10 -19)

<RefObj> interrupt task <Var/Number1> with script <Script Name> and prio <Var/Number2>: arg1=<Value1> arg2=<Value2> arg3=<Value3> arg4=<Value4>

Формирует запрос на прерывание (см. IntReq в статистике объекта) скриптом <Script Name> в стеке Task <Var/Number1> объекта <RefObj> с приоритетом <Var/Number2> и параметрами <Value1> ... <Value4>, но только при условии, что в соответствующем стеке уже запущен хоть 1 скрипт и указанный приоритет <Var/Number2> выше приоритета активного в данном стеке скрипта. Если прерывания разрешены в данном стеке, то запуск скрипта <Script Name> фактически произойдет лишь в момент завершения первой встретившейся за командой interrupt прерываемой команды (т.е. помеченной "@"). И, если такой команды нет вплоть до return, то скрипт <Script Name> запущен не будет.

<RefObj> interrupt with script <Script Name> and prio <Var/Number2> : arg1=<Value1> arg2=<Value2> arg3=<Value3> arg4=<Value4>

Формируют запрос на прерывание текущего скрипта (см. IntReq в статистике объекта) скриптом <Script Name> в стеке Task 0 объекта <RefObj> с приоритетом <Var/Number2> и параметрами <Value1> ... <Value4>, но только при условии, что указанный приоритет <Var/Number2> выше приоритета текущего скрипта. Если прерывания разрешены в данном стеке, то запуск скрипта <Script Name> фактически произойдет лишь в момент завершения первой встретившейся за командой interrupt прерываемой команды (т.е. помеченной "@"). И, если такой команды нет вплоть до return, то скрипт <Script Name> запущен не будет.

<RefObj> interrupt with script <Script Name> and prio <Var/Number2>

Тоже самое что и предыдущая команда, используется в том случае если прерывающий скрипт не имеет аргументов.

<RetVar/IF>get task ID

Возвращает номер стека на объекте, в котором выполняется текущий скрипт. Когда вы пользуетесь командами из главного меню, «Торговые», «Навигационные», «Боевые» и т.д. то запускаемые скрипты имеют свой Task ID. Например: команда покупать или продавать товар будет иметь номер 0, команды управления турелями с 1-6, команды из дополнительного слота 10-11. Также в разделе "Script Task Infos" меню информации об объекте можно увидеть список всех активных стеков (задач) и какие скрипты и с каким приоритетом выполняются в каждом из них.

<RetVar/IF>get PID

Возвращает глобальный идентификатор задачи (PID). Глобальный идентификатор присваивается ScE любому запускаемому процессу и используется движком для внутренних ссылок на процесс, PID для каждого процесса строго индивидуален, это значит, что не может быть двух процессов имеющих одинаковый PID. Посмотреть PID можно в информационном окне объекта (при активированном скрипт-редакторе).

<RefObj> connect ship command/signal <Object Command/Signal> to script <Script Name> with prio <Var/Number>

Устанавливает связь команды/сигнала <Object Command/Signal> с определенным объектом <RefObj>, назначая обработчиком этой команды или сигнала скрипт <Script Name>, и устанавливает его приоритет равным <Var/Number>.

<RefObj> set ship command/signal <Object Command/Signal> to global default behaviour

Восстанавливает стандартный обработчик команды/сигнала <Object Command/Signal> для объекта <RefObj>.

<RefObj> ignore ship command/signal <Object Command/Signal>

Игнорировать команду/сигнал <Object Command/Signal> объектом <RefObj>. То есть после этой инструкции на объекте не будет запускаться обработчик этой команды, даже если он получит соответствующий сигнал или команду.

enable signal/interrupt handling: <Var/Number>

Включает/выключает (TRUE/FALSE) прерывания для всего текущего стека. По умолчанию прерывания разрешены. Команда полезна, если вам требуется исключить прерывание текущего скрипта.

<RetVar/IF> is signal/interrupt handling on

Возвращает состояние флага обработки сигналов/прерываний. [TRUE] если прерывания для текущего стека разрешены и [FALSE] если запрещены.

global script map: set: key=<Object Command/Signal>, class=<Var/Class>, race=<Var/Race>, script=<Script Name>, prio=<Var/Number>

Назначить для команды или сигнала <Object Command/Signal> скрипт обработчик. Установка производится глобально для всех объектов класса <Var/Class> принадлежащих расе <Var/Race> скрипт <Script Name> и установить для него приоритет <Var/Number>. (Назначить скрипт обработчиком команды).

global script map: remove: key=<Object Command/Signal>, class=<Var/Class>, race=<Var/Race>

Отменить (глобально) назначение скрипта обработчика для команды или сигнала <Object Command/Signal> всех объектов класса <Var/Class> принадлежащих расе <Var/Race> скрипта <Script Name>. (Удалить обработчик команды).

global script map: ignore: key=<Object Command/Signal>, class=<Var/Class>, race=<Var/Race>

Исключить обработку скрипта обработчика на объектах определенного типа. Параметры такие же как и у двух предыдущих команд. Пример: установив обработчик сигнала SIGNAL_ATTACKED для объектов класса «Корабль», нам требуется исключить объекты класса «Дрон» выглядеть это будет вот так:

001 global script map: set: key=SIGNAL_ATTACKED, class=Корабль, race=Player, script=скрипт_обработчик, prio=100

002 global script map: ignore: key=SIGNAL_ATTACKED, class=Дрон, race=Player

Теперь назначенный скрипт обработчик будет запускаться при поступлении сигнала SIGNAL_ATTACKED на любом объекте класса «Корабль» за исключением объектов класса «Дрон».

set script command upgrade: command=<Object Command/Signal> upgrade <Var/Ware>

Назначить апгрейд или товар <Var/Ware> который должен быть установлен на объекте для активации команды <Object Command/Signal> в меню объекта. При отсутствии данного апргейда или товара строка в командном меню объекта не отразится. Если <Var/Ware> указать [TRUE] то команда будет появляться всегда.

<RetVar>= get script command upgrade: command= <Object Command/Signal>

Получить в переменную <RetVar> необходимый апгрейд, для активации в командном меню команды <Object Command/Signal> . Если апгрейд не требуется возвращает [TRUE].

set script command <Object Command/Signal>

Установить командой для текущего скрипта команду <Object Command/Signal>.

<RetVar/IF> get script command

Получить команду <RetVar> установленную для текущего скрипта. Также, можно обрабатывать как логическое значение для оператора <IF> установлена [TRUE] не установлена [FALSE]

set script command target <Value>

Установить цель <Value> для команды текущего скрипта

<RetVar/IF> get script command target

Получить цель <RetVar> установленную для команды текущего скрипта или логическое значение [FALSE] если не установлена.

<RetVar> datatyp[ <Value> ]

Получить тип данных <RetVar> переменной <Value> описание типов данных в разделе «Введение в скриптописание Х2 => Переменные. Типы переменных».

<RetVar/IF> is datatyp[ <Value> ] == <Var/Script Data Type>

Получить результат проверки в виде логического [TRUE]|[FALSE] принадлежит или нет, переменная <Value> к типу данных <Var/Script Data Type>.

<RetVar> read text: page=<pageid> id=<textid>

Получить значение из основного языкового ресурса, со страницы <pageid> и идентификатора <textid>. Основной языковой файл загружается во время старта игры или загрузки сохраненной. Этот файл может быть изменен или дополнен дополнительными языковыми файлами подгружаемыми к основному командой load text: id=<languagefileid> и соответственно страницы и ID подгруженные из дополнительных файлов, сразу после догрузки станут доступны для этой команды, но не ранее того.

<RetVar>=sprintf: fmt=<Var/String>, <Value1>, <Value2>, <Value3>, <Value4>, <Value5>

Возвращает строку <Var/String> в которой все теги %s заменены соответствующими значениями параметров <Value>. Первый %s - <Value1>, второй - <value2> и т.д. Применяется для подстановки в заданный шаблон вычисляемых или изменяемых значений. Строка-шаблон вводится в скриптовом редакторе, теги %s вставляются в те места где должны быть вычисляемые значения. Более подробно использование тегов рассмотрено в главе «Языковые файлы XML в Х2».

<RetVar>=sprintf: pageid=<pageid> id=<textid>, <Value1>, <Value2>, <Value3>, <Value4>, <Value5>

То же самое, что и предыдущая функция, только строка-шаблон читается из основного языкового файла, страница <pageid>, строка <textid>

load text: id=<languagefileid>

эта команда на загрузку языкового файла описания с соответствующим ID (ID это номер языкового файла без кода страны, из папки "t"...например, для 70003 - id = 3). Фактически эта команда дополняет основной языковой файл (70001.xml) который загружается во время старта игры, учтите что если в загружаемом вами файле вносятся изменения на страницах и в текстовых идентификаторах которые используются в основном языковом файле, то старые значения будут заменены новыми из загружаемого вами файла. Делается это для того, чтобы вы могли изменять стандартные имена команд и описаний и т.п используемых в игре, а также указать имена и описания для новых товаров, команд и т.д., которые добавлены в игру, иначе мы получим read-text`ы в их описаниях.

<RetVar/IF> state of news article page=<Var/Number> id=<Var/Number>

Получить статус <RetVar/IF> статьи новостей из страницы <Var/Number> с идентификатором <Var/Number>. Эта команда предназначены для работы с BBS-engine отвечающую за формирование досок объявлений на станциях. Подробна работа BBS-engine рассмотрена в статье в разделе «Интерпретатор скриптовых команд».

set state of news article page=<Var/Number> id=<Var/Number> to <Var/Number>

Установить статус статьи новостей из страницы <Var/Number> с идентификатором <Var/Number> равным <Var/Number>. Эта команда предназначены для работы с BBS-engine отвечающую за формирование досок объявлений на станциях. Подробна работа BBS-engine рассмотрена в статье в разделе «Интерпретатор скриптовых команд».

<RetVar/IF> system date is month=<month> day=<day>
Возвращает [TRUE] если системная (не игровая!) дата на компьютере совпадает с запрошенной и [FALSE] в противном случае. В формате месяц, день.

<RetVar>=playing time

Возвращает текущее игровое время в секундах. Подразумевается время от момента, когда была начата текущая игра вообще, а не от последней загрузки.

Infinite loop detection enabled=<Var/Number>

Включает или выключает [TRUE/FALSE] механизм отслеживания и остановки бесконечных циклов. На практике срабатывает редко. Лучшей защитой служит использование инструкций wait в теле любых циклов.

set script command upgrade: command=<Object Command/Signal> upgrade <Var/Ware> script=<script name>

Эта команда работает идентично команде set script command upgrade с тем отличием, что данная инструкция анализирует флаг возвращаемый проверочным скриптом <script name> и позволяет производить многоуровневую проверку условий для активации команды в командном меню объекта. Проверочный скрипт запускается до того как производится установка в меню и возвращает результат в виде флага, сообщающего инструкции о том активировать команду или нет. Если возвращаемый флаг CmdConCheck.Disabled, то строка меню отражается серым цветом и недоступна для выбора, если CmdConCheck.Available, то строка меню становится доступной. Возвращаемое значение должно состоять из двух констант записанных через добавляющее ИЛИ “ | “. Первая константа сообщает инструкции как запускать проверочный скрипт. Эту функцию выполняют константы CmdConCheck.OneTime и CmdConCheck.Infinite они должны стоять первыми в возвращаемом выражении. Вторая часть возвращаемого значения может состоять из любой из четырех констант CmdConCheck.NeedHomeBase, CmdConCheck.NeedHomeStation, CmdConCheck.Available, CmdConCheck.Disabled.

Описание констант возвращаемых скриптом указаны в таблице:

Флаговая Константа | Описание
CmdConCheck.OneTime | Проверочный скрипт запускается однажды во время отображения меню. Соответственно результат обрабатывается однажды, и во время отображения никакой реструктуризации меню не произойдет до тех пор пока меню не будет закрыто и открыто заново.
CmdConCheck.Infinite | Проверочный скрипт будет запускаться циклически все время пока меню отражается. И соответственно реструктуризация может произойти во время отражения меню.
CmdConCheck.NeedHomeBase | Корабль имеет базу приписки
CmdConCheck.NeedHomeStation | Корабль имеет базу приписки станцию а не корабль
CmdConCheck.Available | Команда выполняется
CmdConCheck.Disabled | Команда отключена

В примере мы создадим строку в меню корабля в разделе CUSTOM которая должна запускать скрипт main.script.test только в том случае, когда на объекте имеется хотя бы одна ракета «Шелкопряд» в противном случае строка должна отразится серым цветом и стать недоступной для выбора:

Инициализирующий скрипт.

001   global script map: set: key=COMMAND_TYPE_CUSTOM_15, class=Корабль, race=Player,  script='main.script.test', prio=0
 002   global script map: ignore: key=COMMAND_TYPE_CUSTOM_15, class=Дрон, race=Player
 003   set script command upgrade: command=COMMAND_TYPE_CUSTOM_15  upgrade=[TRUE]   script='a.check..script'
 004   return null

В строке 003 параметр upgrade указываем [TRUE], для того чтобы строка отобразилась в любом случае. Если в upgrade <Var/Ware> указать непосредственно товар то в случае его отсутствия у объекта строка в меню вообще не отобразится. Теперь создаем проверочный скрипт, единственный аргумент будет указывать на объект на котором открыта командное меню (корабль, станция):

Arguments

  • 1: ship , Перем/Корабль , 'ship'

Source Text

001   $flag = [CmdConCheck.OneTime]
 002   if $ship -> get amount of ware Ракета Шелкопряд in cargo bay
 003    $flag = $flag | [CmdConCheck.Available]
 004   else
 005    $flag = $flag | [CmdConCheck.Disabled]
 006   end
 007   return $flag

Обратите внимание на то, что если данная команда будет вызываться из инициализирующего скрипта init.<script name>, то проверочный скрипт при запуске будет записан в скрипткэш. Это означает что после изменений проверочного скрипта необходимо произвести реинициализацию из главного меню редактора Reinit Script Cahes.

<RefObj>set local variable: name=<Var/String> value=<Value>

Устанавливает значение локальной переменной объекта <Var/String> равным <Value>. Локальные переменные привязаны к определенному объекту и используются для обмена данными между скриптами запущенными на одном объекте.

<RetVar/IF><RefObj> get local variable: name=<Var/String>

Возвращает значение локальной переменной объекта <RefObj> с именем <Var/String>. Локальные переменные разных объектов независимы. Эта пара функций может применяться для обмена данными между скриптами выполняемыми на одном объекте. Отменить установку переменной можно задав её значение в null.

set global variable: name=<Var/String> value=<Value>

<RetVar>=get global variable: name=<Var/String>

Пара функций аналогичная предыдущей, но работающая с глобальными переменными. Глобальные переменные не привязаны к какому-либо объекту, а являются общими для всех и доступны любому скрипту.

al engine: register script=<Script Name>

Регистрирует скрипт <Script Name> как плагин к AL (Artificial Life) Engine. Эта команда и три следующих относятся к набору команд для организации работы AL плагинов, т.е. скриптов отвечающих за «искусственную жизнь».

al engine: unregister script=<Script Name>

Снимает регистрацию скрипта <Script Name> как плагина к AL (Artificial Life) Engine.

al engine: set plugin <Var/String1> description to <Var/String2>

Устанавливает описание плагина с идентификатором <Var/String1> равным <Var/String2>

al engine: set plugin <Var/String> timer interval to <Var/Number> s

Устанавливает интервал вызовов плагина <Var/String> по таймеру в <Var/Number> секунд

<RetVar>=get script version

Возвращает версию текущего скрипта

<RetVar>=get script name

Возвращает имя текущего скрипта

<RetVar/IF> is plot <plot> is state <stateflag>

Эта инструкция предназначена для отслеживания прохождения игроком сюжетной линии игры. Все миссии X2-Threat разделены на три основных группы называемые «входными точками», внутри каждой группы, каждая миссия имеет свой «флаг состояния», это цифровой код миссии внутри группы. Данная инструкция возвращает логическое значение [TRUE] в случае если игрок уже выполнил данную миссию, и соответственно [FALSE] в случае если данная миссия еще не выполнена. Описание миссий, «входных точек» и «флагов состояния» приведено в дополнении к данному учебнику в разделе «Точки входа и флаги состояния сюжетной линии».

<RetVar>=get random name: race=<Var/Race>

Возвращает случайно выбранное имя представителя расы <Var/Race> состоящие из имени и фамилии.

<RetVar>=get Khaak agression level

Возвращает текущий уровень агрессивности Хааков.

set Khaak agression level to <Var/Number>

Устанавливает уровень агрессивности Хааков. Значение может лежать в пределах от 0 до 100, стандартный уровень 15. Влияет на количество и размер кластеров в группах совершающих набеги на сектора.

· Команды исполнения

end conditional

Конец условия или цикла. Любой цикл или условие должно завершаться этим оператором, иначе редактор при попытке сохранить скрипт выдаст ошибку.

Else

Оператор ИНАЧЕ располагается в теле условия IF…(операторы выполняющиеся если ИСТИНА)…ELSE…(операторы если ЛОЖЬ)…END. Если используется IF NOT то: IF NOT…(операторы выполняющиеся если ЛОЖЬ)…ELSE…(операторы если ИСТИНА)…END

Continue

Начать следующий виток цикла. Передает управление на начало выполняемого цикла, то есть на ближайший сверху оператор WHILE/

break

Прервать выполнение цикла. Передает управление в строку следующую за оператором END, завершающего выполняемый цикл.

goto label <Label>

Перейти к метке <label>.

define label <Label>

Определить метку для команды goto.

· Вызов скриптов

@<RetVar/IF/START> <RefObj> call script <Script Name>: <Parameter>

Запускает скрипт <Script Name> в стеке Task 0 объекта <RefObj> (либо в текущем стеке текущего объекта если не использован префикс START) с параметрами <Parameter> и приоритетом текущего скрипта. Возвращаемое скриптом значение присваивается переменной <RetVar> или анализируется в <IF>. Допускается игнорирование возвращаемого значения (отсутствие <RetVar/IF>). Если <RefObj> = null и использован префикс START, то скрипт будет запущен как глобальный. При запуске в текущем стеке (т.е. без префикса START) команда call script ничего не удаляет из текущего стека. В противном случае из стека Task 0 объекта <RefObj> будут удалены все остальные скрипты независимо от приоритетов. Указание префикса <START> означает продолжение выполнения текущего скрипта, без ожидания завершения вызванного. При этом скрипт будет запущен строго в стеке Task 0 объекта <RefObj>, удалив при этом все остальные скрипты из этого стека.

Внимание! Никогда не используйте @ START [THIS]->call script в скрипте, запущенном в Task 0 объекта! Скрипт не будет запущен, а текущий повиснет! Также будьте внимательны с запуском без префикса START и с <RefObj> отличным от [THIS], т.к. если объект <RefObj> будет уничтожен, вызванный скрипт сам остановлен при этом не будет, он будет продолжать выполняться на текущем объекте и может повиснуть.

return <Value>

Завершить выполнение скрипта и вернуть результат исполнения <Value> вызывавшему скрипту.

· Массивы

<RetVar>=array alloc: size=<Var/Number>

Создать массив размером <Var/Number> элементов и вернуть переменную <RetVar> типа массив. На самом деле возвращается указатель на массив, то есть ScE определяет область памяти под указанное количество элементов и возвращает указатель на него.

<RetVar/IF> <Var/Array>[<Var/Number>]

Присвоить переменной <RetVar/IF> значение, из элемента с индексом <Var/Number>, массива <Var/Array> .

<Var/Array>[<Var/Number>]=<Value>

Записать в элемент массива <Var/Array> с индексом <Var/Number> значение <Value>.

<RetVar>=size of array <Var/Array>

Получить в переменную <RetVar> размер массива <Var/Array>.

<RetVar>=clone array <Var/Array>: index <Var/Number> <Var/Number>

Создать копию массива <Var/Array> начиная с индекса <Var/Number> по индекс <Var/Number>, в другой области памяти и вернуть указатель на нее в переменную <RetVar>. Если вам нужна копия массива, то используйте именно эту команду, т.к. попытка скопировать массив при помощи конструкции $array2=$array1 не годится. Такая конструкция запишет в переменную $array2 указатель на область памяти где храниться массив array1, соответственно в памяти будет существовать один массив и обе переменные будут указывать на него. Подробно это описано в главе «Введение в скриптописание Х2».

copy array <Var/Array> index <Var/Number> <Var/Number> into array <Var/Array> at index <Var/Number>

Скопировать элементы массива <Var/Array> начиная с индекса <Var/Number> по индекс <Var/Number> в массив <Var/Array> начиная с индекса <Var/Number>. Если копируемый сегмент превысит размер массива-приемника, то размер массива-приемника будет увеличен на требуемое количество элементов.

insert <Value> into array <Var/Array> at index <Var/Number>

Вставить в массив <Var/Array> новый элемент <Value> на место элемента с индексом <Var/Number>. (Фактически изменить размер массива. Индексы всех элементов массива начиная с заданного увеличатся на 1).

append <Value> to array <Var/Array>

Добавить в конец массива <Var/Array> новый элемент <Value>. (Фактически изменить размер массива).

remove element from array <Var/Array> at index <Var/Number>

Удалить элемент с индексом <Var/Number> из массива <Var/Array>. (Фактически изменить размер массива. Индексы всех элементов начиная с заданного уменьшатся на 1).

resize array <Var/Array> to <Var/Number>

Установить размер массива <Var/Array> равной <Var/Number>. (Если размер массива уменьшается то «лишние» элементы окажутся обрезанными, если увеличивается то в массив добавляются пустые элементы).


Полный список команд Х2

Полный список команд ScE X2(v1.4)

1 Общие команды

1.001 <RetVar/IF><Expression>
1.002 inc <RetVar> =
1.003 dec <RetVar> =
1.004 @ <RetVar/IF> wait <Var/Number> ms
1.005 @ <RetVar/IF> wait randomly fo <Var/Number> to <Var/Number> ms
1.006 <Var> = random value from 0 to <Var/Number> -1
1.007 <Var> = random value from <Var/Number> to <Var/Number> -1
1.008 *<Comment>
1.009 <RetVar> = script engine version
1.010 <Var> = get script priority
1.011 set secript priority to <Var/Number>
1.012 <RetVar/IF> is script with prio <Var/Number> on stack
1.0121 <RefObj> interrupt with script <Script Name> and prio <Var/Number>: arg1=<Value> arg2=<Value> arg3=<Value> arg4=<Value>
1.013 <RetVar/IF> get task id
1.014 <RetVar/IF> get global task id
1.015 <RefObj> interrupt with script <Script Name> and prio <Var/Number>
1.016 <RefObj> connect ship command/signal <Object Command/Signal> to script <Script Name> with prio <Var/Number>
1.017 <RefObj> set ship command/signal <Object Command/Signal>
1.018 <RefObj> ignore ship command/signal <Object Command/Signal>
1.019 enable signal/interrupt handling: <Var/Number>
1.020 <RetVar/IF> is signal/interrupt handling on
1.021 global ship map: set: key=<Object Command/Signal>,class=<Var/Class>,race=<Var/Race>,script=<Script Name>,prio=<Var/Number>
1.022 global ship map: remove: key=<Object Command/Signal>,class=<Var/Class>,race=<Var/Race>
1.023 global ship map: ignore: key=<Object Command/Signal>,class=<Var/Class>,race=<Var/Race>
1.024 set ship command upgrade: command=<Object Command/Signal> upgrade=<Var/Ware>
1.025 <RetVar> = get ship command upgrade: command=<Object Command/Signal>
1.026 set script command: <Object Command/Signal>
1.027 <RetVar/IF> get script command
1.028 set script command target: <Value>
1.029 <RetVar/IF> get script command target
1.030 <RetVar> = datatyp[<Value>]
1.031 <RetVar/IF> is datatyp[<Value>] == <Var/Script Data Type>
1.032 <RetVar> = read text: page=<Var/Number> id=<Var/Number>
1.033 <RetVar> = sprintf: fmt=<Var/String>,<Value>,<Value>,<Value>,<Value>,<Value>
1.034 <RetVar> = sprintf: pageid=<Var/Number> textid=<Var/Number>,<Value>,<Value>,<Value>,<Value>,<Value>
1.035 load text: id=<Var/Number>
1.036 <RetVar> = state of news article: page=<Var/Number> id=<Var/Number>
1.037 set state of news article: page=<Var/Number> id=<Var/Number> to <Var/Number>
1.038 <RetVar/IF> system date is month=<Var/Number>,day=<Var/Number>
1.039 <RetVar> = playing time
1.040 infinite loop detection enabled=<Var/Number>
1.041 set ship command upgrade: command=<Object Command/Signal> upgrade=<Var/Ware> script=<Script Name>
1.042 <RefObj> set local variable: name=<Var/String> value=<Value>
1.043 <RetVar/IF> <RefObj> get local variable: name=<Var/String>
1.044 set global variable: name=<Var/String> value=<Value>
1.045 <RetVar/IF> get global variable: name=<Var/String>
1.046 al engine: register script = <script name>
1.047 al engine: unregister script <script name>
1.048 al engine: set plugin <value> description to <string>
1.049 al engine: set plugin <value> timer interval to <number> s
1.050 <RetVar/IF> = is plot <number> state flag <value>
1.051 <RetVar> = get script version
1.052 <RetVar> = get script name
1.053 <RefObj> -> interrupt task <number> with script <script name> and prio <number>: arg1=<value> arg2=<value> arg3=<value> arg4=<value>
1.054 <RefObj> -> start task <number> with script <script name> and prio <number>: arg1=<value> arg2=<value> arg3=<value> arg4=<value> arg5=<value>
1.055 <RetVar/IF> = <RefObj> -> get tradeable ware array from station
1.056 <RetVar/IF> = get Khaak aggression level
1.057 <RetVar/IF> = get random name: race=<race>
1.058 set Khaak aggression level to <number>

1.1 Общие команды ->Команды исполнения

1.1.001 end conditional
1.1.002 else
1.1.003 continue
1.1.004 break
1.1.005 goto label <Label>
1.1.006 define label <Label>

1.2 Общие команды ->Вызов скриптов

1.2.001 @ <RetVar/IF/START> <RefObj> call script <Script Name>:<Parameter>
1.2.002 return <Value>

1.3 Общие команды->Массивы

1.3.001 <RetVar> = array alloc: size=<Var/Number>
1.3.002 <RetVar/IF> <Var/Array>[<Var/Number>]
1.3.003 <Var/Array>[<Var/Number>] = <Value>
1.3.004 <RetVar> = size of array <Var/Array>
1.3.005 <RetVar> = clone array <Var/Array>: index <Var/Number> ... <Var/Number>
1.3.006 copy array <Var/Array> index <Var/Number> ... <Var/Number> into array <Var/Array> at index <Var/Number>
1.3.007 insert <Value> into array <Var/Array> at index <Var/Number>
1.3.008 append <Value> to array <Var/Array>
1.3.009 remove element from array <Var/Array> at index <Var/Number>
1.3.010 resize array <Var/Array> to <Var/Number>

2 Аудио команды

2.001 play sample <Var/Number>
2.002 play sample: incoming transmission <Var/Number>, from object <Value>
2.003 <RefObj> send audio message <Var/Number> to player
2.004 send incoming message <Var/String> to player: display it=<Var/Number>
2.005 <RetVar/IF/START> -> speak text: page=<number> id=<number> priority=<number>

3 Команды работы с бортовым журналом

3.001 write to player logbook <Value>
3.002 write to player logbook: sprintf: fmt=<Var/String>,<Value>,<Value>,<Value>,<Value>,<Value>
3.003 write to player logbook: sprintf: pageid=<Var/Number> textid=<Var/Number>,<Value>,<Value>,<Value>,<Value>,<Value>
3.004 <RefObj> write to logbook <Value>
3.005 write to log file #<Var/Number> append=<Var/Number> value=<Value>
3.006 write to log file #<Var/Number> append=<Var/Number> printf: fmt=<Var/String>, <Value>, <Value>, <Value>, <Value>, <Value>
3.007 write to log file #<Var/Number> append=<Var/Number>[/color] printf: pageid=<Var/Number> textid=<Var/Number>, <Value>, <Value>, <Value>, <Value>, <Value>

4 Навигационные команды

4.001 @ <RetVar/IF> <RefObj> fly to home base
4.002 @ <RetVar/IF> <RefObj> fly to station <Var/Station>
4.003 @ <RetVar/IF> <RefObj> fly to sector <Var/Sector>
4.004 <RetVar/IF> <RefObj> find nearest enemy ship: max.dist=<Var/Number>
4.005 <RetVar/IF> <RefObj> find nearest enemy station: max.dist=<Var/Number>
4.006 <RetVar/IF> <RefObj> fire lasers on target <Value> using turret <Var/Number>
4.007 @ <RetVar/IF> <RefObj> turn turret <Var/Number> to target <Var/Ship/Station>: timeout=<Var/Number> ms
4.008 @ <RetVar/IF> <RefObj> attack run on target <Value>: timeout=<Var/Number> ms
4.009 @ <RetVar/IF> <RefObj> defensive move: type=<Var/Number>,intensity=<Var/Number>,timeout=<Var/Number> ms,avoid object=<Value>
4.010 @ <RetVar/IF> <RefObj> move to ware object <Value> for collecting: timeout=<Var/Number> ms
4.011 <RetVar/IF> <RefObj> catch ware object <Value>
4.012 @ <RetVar/IF> <RefObj> move around <Var/Number> ms
4.013 @ <RetVar/IF> <RefObj> escort ship <Var/Ship>
4.014 @ <RetVar/IF> <RefObj> escort ship <Var/Ship>: timeout=<Var/Number> ms
4.015 <RefObj> set formation <Var/Number>
4.016 <RefObj> add to formation with leader <Var/Ship>
4.017 <RefObj> remove from any formation
4.018 <RetVar/IF> <RefObj> get formation leader
4.019 <RetVar> = <RefObj> get formation follower ships
4.010 START <RefObj> command <Object Command>: arg1=<Value>,arg2=<Value>,arg3=<Value>,arg4=<Value>
4.021 <RefObj> send signal <Object Signal>: arg1=<Value>,arg2=<Value>,arg3=<Value>,arg4=<Value>
4.022 @ <RetVar/IF> <RefObj> follow object <Var/Ship> with precision <Var/Number> m
4.023 @ <RetVar/IF> <RefObj> follow <Var/Ship> with precision <Var/Number> m: timeout=<Var/Number> ms
4.024 <RefObj> set follow mode <Var/Number>
4.025 <RetVar/IF> <RefObj> get follow mode
4.026 <RefObj> set destination to <Value>
4.027 <RetVar/IF> <RefObj> get destination
4.028 <RefObj> set attack target to <Value>
4.029 <RetVar/IF> <RefObj> get attack target
4.030 @ <RetVar/IF> <RefObj> move to position x=<Var/Number> y=<Var/Number> z=<Var/Number> with precision <Var/Number> m
4.031 <RefObj> set command: <Object Command>
4.032 <RetVar/IF> <RefObj> get command
4.033 <RefObj> set command target: <Value>
4.034 <RetVar/IF> <RefObj> get command target
4.035 <RefObj> set command target2: <Value>
4.036 <RetVar/IF> <RefObj> get command target2
4.037 <RetVar> = <RefObj> select new formation leader by: ship class=<Var/Number> strength)<Var/Number> min.speed=<Var/Number>
4.038 <RetVar/IF> <RefObj> has formation ships
4.039 <RefObj> give formation leadership to <Var/Ship>
4.040 <RefObj> set tactical to <Var/Number>
4.041 <RetVar> = <RefObj> get tactical
4.042 <RetVar/IF> get player tracking aim
4.043 <RetVar/IF> <RefObj> is <Var/Ship/Station> in firing range of turret <Var/Number>
4.044 <RetVar> = <RefObj> find enemy in firing range of turret <Var/Number>
4.045 <RefObj> set command: <Object Command> target=<Value> target2=<Value> par1=<Value> par2=<Value>
4.046 <RetVar/IF> <RefObj> fire missile <Var/Ware> on <Value>
4.047 <RetVar/IF> <RefObj> get current missile
4.048 <RetVar/IF> <RefObj> find best missile for target <Value>
4.049 <RetVar> = best missile type for target <Value>
4.050 <RetVar/IF> <RefObj> launch <Var/Number> fight drones: protect me or attack target=<Value>
4.051 <RetVar/IF> <RefObj> is missile <Var/Ware> ready to fire
4.052 <RetVar/IF> <RefObj> should a missile be fired
4.053 <RetVar> = <RefObj> get fire missile probability
4.054 <RetVar> = <RefObj>get fire missile time difference in seconds
4.055 <RefObj> set fire missile probability to <Var/Number>
4.056 <RefObj> set fire missile time difference to <Var/Number> s
4.057 <RetVar/IF> <RefObj> fits laser <Var/Ware> into turret <Var/Number>
4.058 <RetVar> = <RefObj> get max. number of lasers in turret <Var/Number>
4.059 <RetVar> = <RefObj> get laser type in turret <Var/Number> at slot <Var/Number>
4.060 <RetVar> = <RefObj> get number of turrets
4.061 <RetVar> = get range of missile type <Var/Ware>
4.062 <RetVar> = <RefObj> find nearest missile aiming to me
4.063 <RetVar/IF> <RefObj> decouple ships
4.064 <RetVar/IF> <RefObj> is decoupled ships leader
4.065 <RetVar/IF> <RefObj> get current galaxy flight timestep in ms
4.066 <RetVar/IF> <RefObj> is landing
4.067 <RetVar/IF> <RefObj> is starting
4.068 <RetVar/IF> <RefObj> use jump drive: target=<Value>
4.069 <RetVar/IF> <RefObj> needed jump drive energy for jump to sector <Var/Sector>
4.070 <RetVar/IF> <RefObj> check, select and fire missile on <Value>
4.071 <RetVar/IF> = <RefObj> -> add big ship <dock>
4.072 <RetVar/IF> = <RefObj> -> has a free big ship dock slot
4.073 <RetVar/IF> = <RefObj> -> can be controlled by race logic
4.074 <RefObj> -> set race logic control enabled to <boolean>
...description: if (enabled == false).....{ NPC ship of normal 5 races will not start doing it's own thing}
4.075 <RetVar/IF> = <RefObj> -> can execute StartAction
4.076 <RefObj> -> set StartAction enabled to <boolean>
4.077 set as player wingman: <ship>
4.078 <RetVar/IF> = <RefObj> -> is player wingman

5 Торговые команды

5.001 <RetVar/IF> get player money
5.002 add money to player: <Var/Number>
5.003 <RetVar/IF> <RefObj> add <Var/Number> units of <Var/Ware>
5.004 <RetVar/IF> <RefObj> install <Var/Number> units of <Var/Ware>
5.005 <RetVar> = get volume of ware <Var/Ware>
5.006 <RetVar> = get transport class of ware <Var/Ware>
5.007 <RetVar/IF> find station: product <Var/Ware> with best price: max.price=<Var/Number>,amount=<Var/Number>,max.jumps=<Var/Number>,startsector=<Var/Sector>,trader=<Var/Ship/Station>
5.008 <RetVar/IF> find station: product <Var/Ware> with min. jumps: max.price=<Var/Number>,amount=<Var/Number>,max.jumps=<Var/Number>,startsector=<Var/Sector>,trader=<Var/Ship/Station>
5.009 <RetVar/IF> find station: resource <Var/Ware> with best price: min.price=<Var/Number>,amount=<Var/Number>,max.jumps=<Var/Number>,startsector=<Var/Sector>,trader=<Var/Ship/Station>
5.010 <RetVar/IF> find station: resource <Var/Ware> with min. jumps: min.price=<Var/Number>,amount=<Var/Number>,max.jumps=<Var/Number>,startsector=<Var/Sector>,trader=<Var/Ship/Station>
5.011 <RetVar/IF> find station sells: resource <Var/Ware> with best price: max.price=<Var/Number>,amount=<Var/Number>,max.jumps=<Var/Number>,startsector=<Var/Sector>,trader=<Var/Ship/Station>
5.012 <RetVar/IF> find station sells: resource <Var/Ware> with min. jumps: max.price=<Var/Number>,amount=<Var/Number>,max.jumps=<Var/Number>,startsector=<Var/Sector>,trader=<Var/Ship/Station>
5.013 <RetVar> = get average price of ware <Var/Ware>
5.014 <RetVar> = get max price of ware <Var/Ware>
5.015 <RetVar> = get min price of ware <Var/Ware>
5.016 <RetVar> = get max price of ware <Var/Ware> as secondary resourcer
5.017 <RetVar> = get min price of ware <Var/Ware> as secondary resourcer
5.018 <RetVar/IF> is ware <Var/Ware> illegal in <Var/Race> sectors
5.019 <RetVar> = get maintype of ware <Var/Ware>
5.020 <RetVar> = get subtype of ware <Var/Ware>
5.021 <RetVar> = get ware from maintype <Var/Number> and subtype <Var/Number>
5.022 <RetVar> = get number of subtypes of maintype <Var/Number>
5.023 <RetVar> = <RefObj> get maintype
5.024 <RetVar> = <RefObj> get subtype
5.025 <RetVar/IF> = <RefObj> -> find station: product <ware> with best price: max.price=<number>, amount=<number>, max.jumps=<number>, startsector=<sector>, trader=<refobj>
5.026 <RetVar/IF> = <RefObj> -> find station: product <ware> with min. jumps: max.price=<number>, amount=<number>, max.jumps=<number>, startsector=<sector>, trader=<refobj>
5.027 <RetVar/IF> = <RefObj> -> find station: resource <ware> with best price: min.price=<number>, amount=<number>, max.jumps=<number>, startsector=<sector>, trader=<refobj>
5.028 <RetVar/IF> = <RefObj> -> find station: resource <ware> with min. jumps: min.price=<number>, amount=<number>, max.jumps=<number>, startsector=<sector>, trader=<refobj>
5.029 <RetVar/IF> = <RefObj> -> find station sells: resource <ware> with best price: max.price=<number>, amount=<number>, max.jumps=<number>, startsector=<sector>, trader=<refobj>
5.030 <RetVar/IF> = <RefObj> -> find station sells: resource <ware> with min. jumps: max.price=<number>, amount=<number>, max.jumps=<number>, startsector=<sector>, trader=<refobj>

5.1 Торговые команды ->для кораблей

5.1.001 <RetVar/IF> <RefObj> buy <Var/Number> units of <Var/Ware>
5.1.002 <RetVar/IF> <RefObj> buy <Var/Number> units of <Var/Ware> to a max. price of <Var/Number> Cr
5.1.003 <RetVar/IF> <RefObj> sell <Var/Number> units of <Var/Ware>
5.1.004 <RetVar/IF> <RefObj> load <Var/Number> units of <Var/Ware>
5.1.005 <RetVar/IF> <RefObj> unload <Var/Number> units of <Var/Ware>
5.1.006 <RetVar> = <RefObj> get max. ware transport class
5.1.007 <RetVar/IF> <RefObj> get cargo bay size
5.1.008 <RetVar/IF> <RefObj> get free volume of cargo bay
5.1.009 <RetVar/IF> <RefObj> get volume of ware <Var/Ware> in cargo bay
5.1.010 <RetVar/IF> <RefObj> get true volume of ware <Var/Ware> in cargo bay
5.1.011 <RetVar/IF> <RefObj> get free volume of ware <Var/Ware> in cargo bay
5.1.012 <RetVar/IF> <RefObj> get total volume in cargo bay
5.1.013 <RetVar/IF> <RefObj> can transport ware <Var/Ware>
5.1.014 <RefObj> add default items to ship
5.1.015 <RefObj> switch laser in slot <Var/Number> to <Var/Ware>
5.1.016 <RefObj> set wanted ware count to <Var/Number>
5.1.017 <RefObj> set wanted ware to <Var/Ware>
5.1.018 <RetVar> = <RefObj> get wanted ware count
5.1.019 <RetVar> = <RefObj> get wanted ware
5.1.020 <RetVar/IF> <RefObj> has illegal ware onboard: race=<Var/Race>

5.2 Торговые команды ->для станций

5.2.001 <RetVar/IF> <RefObj> get best store amount of ware <Var/Ware>
5.2.002 <RetVar/IF> <RefObj> get max. store amount of ware <Var/Ware>
5.2.003 <RetVar/IF> <RefObj> can buy ware <Var/Ware>
5.2.004 <RetVar/IF> <RefObj> can sell ware <Var/Ware>
5.2.005 <RetVar/IF> <RefObj> get price of ware <Var/Ware>
5.2.006 <RetVar/IF> <RefObj> get average price of ware <Var/Ware>
5.2.007 <RefObj> set price of ware <Var/Ware> to <Var/Number> Cr
5.2.008 <RetVar/IF> <RefObj> uses ware <Var/Ware> as primary resource
5.2.009 <RetVar/IF> <RefObj> uses ware <Var/Ware> as secondary resource
5.2.010 <RetVar/IF> <RefObj> trades with ware <Var/Ware>
5.2.011 <RetVar/IF> <RefObj> get product ware
5.2.012 <RetVar/IF> <RefObj> get number of resources
5.2.013 <RetVar/IF> <RefObj> get number of primary resources
5.2.014 <RetVar/IF> <RefObj> get number of secondary resources
5.2.015 <RetVar/IF> <RefObj> get max trade jumps
5.2.016 <RetVar/IF> <RefObj> only player own ships can trade with

5.3 Торговые команды->для кораблей и станций

5.3.001 <RetVar/IF> <RefObj> get money
5.3.002 <RefObj> add money: <Var/Number>
5.3.003 <RetVar/IF> <RefObj> get amount of <Var/Ware> in cargo bay
5.3.004 <RetVar/IF> <RefObj> get true amount of <Var/Ware> in cargo bay
5.3.005 <RetVar/IF> <RefObj> get free amount of <Var/Ware> in cargo bay
5.3.006 <RetVar/IF> <RefObj> get max amount of <Var/Ware> that can be stored in cargo bay

6 Работа с объектами

6.001 <RetVar/IF> <RefObj> get object class
6.002 <RetVar/IF> <RefObj> get owner race
6.003 <RetVar/IF> <RefObj> get environment
6.004 <RetVar/IF> <RefObj> get sector
6.005 <RetVar/IF> <RefObj> get homebase
6.006 <RetVar/IF> <RefObj> is of class <Var/Class>
6.007 <RetVar/IF> <RefObj> exists
6.008 <RetVar/IF> <RefObj> get ware type code of object
6.009 <RetVar/IF> <RefObj> get serial name of station
6.010 <RetVar/IF> find station in galaxis: startsector= <Var/Sector> class or type=<Value> race=<Var/race> flags=<Var/Number> refobj=<Value> serial=<Var/String> max.jumps=<Var/Number>
6.011 <RetVar/IF> <RefObj> is of type <Var/Ship Type/Station Type>
6.012 <RetVar/IF> get jumps from sector <Var/Sector> to sector <Var/Sector>
6.013 <RetVar/IF> get next sector on route from sector <Var/Sector> to sector <Var/Sector>
6.014 <RefObj> set homebase to <Var/Ship/Station>
6.015 <RetVar/IF> <RefObj> get current shield strength
6.016 <RetVar/IF> <RefObj> get maximum shield strength
6.017 <RetVar/IF> <RefObj> get current laser strength
6.018 <RetVar/IF> <RefObj> get maximum laser strength
6.019 <RetVar/IF> <RefObj> get maximum laser strength in turret <Var/Number>
6.020 <RetVar/IF> <RefObj> get max. shield type that can be installed
6.021 <RetVar/IF> <RefObj> get number of shild bays
6.022 <RetVar/IF> <RefObj> get number of laser bays
6.023 <RetVar/IF> <RefObj> get max. missile type that can be installed
6.024 <RetVar/IF> <RefObj> get relation to object <Var/Ship/Station>
6.025 <RetVar/IF> <RefObj> get relation to race <Var/Race>
6.026 <RetVar/IF> <RefObj> get notoriery to race <Var/Race>
6.027 <RetVar/IF> get notoriery from race <Var/Race> to race <Var/Race>
6.028 <RetVar/IF> <RefObj> is <Var/Ship/Station> a enemy
6.029 <RetVar/IF> <RefObj> is <Var/Ship/Station> a friend
6.030 <RetVar/IF> <RefObj> is <Var/Ship/Station> neutral to me
6.031 <RetVar/IF> <RefObj> get shield type in bay <Var/Number>
6.032 <RetVar/IF> <RefObj> get laser type in bay <Var/Number>
6.033 <RetVar/IF> <RefObj> has same environment as <Var/Ship/Station>
6.034 <RetVar/IF> <RefObj> is in same sector as <Var/Ship/Station>
6.035 <RetVar/IF> <RefObj> is landed
6.036 <RetVar/IF> <RefObj> is docked
6.037 <RetVar/IF> <RefObj> is docking possible of <Value>
6.038 <RetVar/IF> <RefObj> is docking allowed at <Var/Ship/Station>
6.039 <RetVar/IF> <RefObj> is in sector
6.040 <RetVar/IF> <RefObj> get attacker
6.041 <RefObj> set attacker to <Var/Ship/Station>
6.042 <RetVar> = get distance between <Var/Ship/Station> and <Var/Ship/Station>
6.043 <RetVar> = <RefObj> get distance to: x=<Var/Number> y=<Var/Number> z=<Var/Number>
6.044 <RetVar> = <RefObj> get distance to: position array=<Var/Array>
6.045 <RetVar> = get distance: position array1=<Var/Array> array2=<Var/Array>
6.046 <RetVar> = create ship: type=<Var/Ship Type> owner=<Var/Race> addto=<Value> x=<Var/Number> y=<Var/Number> z=<Var/Number>
6.047 <RetVar> = <RefObj> get x position
6.048 <RetVar> = <RefObj> get y position
6.049 <RetVar> = <RefObj> get z position
6.050 <RetVar> = <RefObj> get position as array
6.051 <RetVar> = get player ship
6.052 <RefObj> set relation against <Var/Ship/Station> to <Relation>
6.053 <RetVar> = create station: type=<Var/Station Type> owner=<Var/Race> addto=<Var/Sector> x=<Var/Number> y=<Var/Number> z=<Var/Number>
6.054 <RetVar> = create gate: type=<Var/Number> addto=<Var/Sector> gateid=<Var/Number> dstsecx=<Var/Number dstsecy=[color=#BBBBBB]<Var/Number> dstgateid=<Var/Number> x=<Var/Number> y=<Var/Number> z=<Var/Number>
6.055 <RetVar> = create asteroid: addto=<Var/Sector> resource=<Var/Number> yield=<Var/Number> x=<Var/Number> y=<Var/Number> z=<Var/Number>
6.056 <RefObj> add product to factory or dock: <Var/Ware>
6.057 <RefObj> add primary resource to factory: <Var/Ware>
6.058 <RefObj> add secondary resource to factory: <Var/Ware>
6.059 <RefObj> remove product from factory or dock: <Var/Ware>
6.060 <RefObj> remove primary resource from factory: <Var/Ware>
6.061 <RefObj> remove secondary resource from factory: <Var/Ware>
6.062 <RetVar> = create nebular: type=<Var/Number> addto=<Var/Sector> x=<Var/Number> y=<Var/Number> z=<Var/Number>
6.063 <RetVar> = create sun: subtype=<Var/Number> r=<Var/Number> g=<Var/Number> b=<Var/Number> addto=<Var/Sector> x=<Var/Number> y=<Var/Number> z=<Var/Number>
6.064 <RetVar> = create planet: subtype=<Var/Number> addto=<Var/Sector> x=<Var/Number> y=<Var/Number> z=<Var/Number>
6.065 <RetVar> = create special: type=<Var/Number> addto=<Var/Sector> x=<Var/Number> y=<Var/Number> z=<Var/Number>
6.066 <RetVar/IF> find ship: sector=<Var/Sector> class or type=<Value> race=<Var/Race> flags=<Var/Number> refobj=<Value> maxdist=<Var/Number> maxnum=<Var/Number> refpos=<Var/Array>
6.067 <RetVar/IF> find asteroid: sector=<Var/Sector> resourcetype=<Var/Number> min.yield=<Var/Number> flags=<Var/Number> refobj=<Value> maxdist=<Var/Number> maxnum=<Var/Number> refpos=<Var/Array>
6.068 <RetVar/IF> find flying ware: sector=<Var/Sector> maintype=<Var/Number> subtype=<Var/Number> flags=<Var/Number> refobj=<Value> maxdist=<Var/Number> maxnum=<Var/Number> refpos=<Var/Array>
6.069 <RetVar/IF> find station: sector=<Var/Sector> class or type=<Value> race=<Var/Race> flags=<Var/Number> refobj=<Value> maxdist=<Var/Number> maxnum=<Var/Number> refpos=<Var/Array>
6.070 <RetVar/IF> <RefObj> is disabled
6.071 <RefObj> station trade and production tasks: on=<Var/Number>
6.072 <RetVar/IF> <RefObj> get SectorObjectID
6.073 <RetVar> = get ware type of SectorObject <Var/Number>
6.074 <RetVar/IF> exists SectorObject <Var/Number>
6.075 <RetVar/IF> get object from SectorObject <Var/Number>
6.076 <RefObj> destruct: show no explosion=<Var/Number>
6.077 <RefObj> set position: x=<Var/Number> y=<Var/Number> z=<Var/Number>
6.078 <RefObj> set rotation: alpha=<Var/Number> beta=<Var/Number> gamma=<Var/Number>
6.079 set position of sector object <Var/Number>: x=<Var/Number> y=<Var/Number> z=<Var/Number>
6.080 set safe positon of sector object <Var/Number>: x=<Var/Number> y=<Var/Number> z=<Var/Number>
6.081 set rotation of sector object <Var/Number>: x=<Var/Number> y=<Var/Number> z=<Var/Number>
6.082 <RetVar> = create sector object: maintype=<Var/Number> subtype=<Var/Number>
6.083 free sector object <Var/Number>
6.084 kill sector object <Var/Number>: reason=<Var/Number>, killer sector object=<Var/Number>
6.085 start sector object <Var/Number> in space <Var/Number>
6.086 <RetVar> = create flying ware: maintype=<Var/Number> subtype=<Var/Number> count=<Var/Number> sector=<Var/Sector> x=<Var/Number> y=<Var/Number> z=<Var/Number> selfdestruct=<Var/Number>
6.087 <RetVar> = <RefObj> get rot alpha
6.088 <RetVar> = <RefObj> get rot beta
6.089 <RetVar> = <RefObj> get rot gamma
6.090 <RetVar> = <RefObj> get size of object
6.091 <RetVar/IF> <RefObj> get max upgrades for upgrade <Var/Ware>
6.092 <RetVar/IF> <RefObj> get max speed
6.093 <RetVar/IF> <RefObj> get max hull
6.094 <RetVar/IF> <RefObj> get hull
6.095 <RetVar/IF> <RefObj> get hull percent
6.096 <RetVar/IF> <RefObj> get shield percent
6.097 <RetVar/IF> <RefObj> get shield and hull percent
6.098 <RetVar/IF> <RefObj> get max upgraded speed
6.099 <RetVar/IF> <RefObj> get dock bay size
6.100 <RetVar/IF> <RefObj> get number of landed ships
6.101 player loses police licence for race <Var/Race>
6.102 <Var/Race> add notoriety: race=<Var/Race> value=<Var/Number>
6.103 <RefObj> set ship disabled to <Var/Number>
6.104 <RefObj> -> put into environment <sector/station/bigship>
6.105 <RefObj> -> station send defend squad against ship <ship>
6.106 <RetVar/IF> = <RefObj> -> get name
6.107 <RefObj> -> set name to <string>
6.108 <RefObj> -> set owner race to <race>
6.109 <RetVar/IF> = <RefObj> -> find ship: class or type=<class/type> race=<race> flags=<flags> refobj=<refobj> maxnum=<number> with homebase=<station>
...description: Environment = RefObj; find ship in Environment.... ;

6.110 <RetVar/IF> = find station in galaxy: startsector=<sector> class or type=<class/type> race=<race> flags=<flags> refobj=<refobj> serial=<id> max.jumps=<number> num=<number>
6.111 <RetVar/IF> = <RefObj> -> get ID code
6.112 <RetVar/IF> = <RefObj> -> get pilot name
6.113 <RefObj> -> set pilot name to <string>
6.114 <RefObj> -> set pilot speaker: voice=<number>, face=<number>, Pirate subrace=<number>, Argon female=<number>
6.115 <RefObj> -> set serial name of station to <Var/Station Serial>

7 Работа с галактикой и секторами

7.001 <RetVar/IF> get sector from universe index: x=<Var/Number>, y=<Var/Number>
7.002 <RetVar> = get max sectors in x direction
7.003 <RetVar> = get max sectors in y direction
7.004 <RetVar/IF> <RefObj> is sector known by the player
7.005 <RetVar> = <RefObj> get universe x index
7.006 <RetVar> = <RefObj> get universe y index
7.0061 <RetVar> = <RefObj> get warp gate: gate id=<Var/Number>
7.007 <RetVar> = <RefObj> get north warp gate
7.008 <RetVar> = <RefObj> get south warp gate
7.009 <RetVar> = <RefObj> get east warp gate
7.010 <RetVar> = <RefObj> get west warp gate
7.011 <RetVar> = find a random sector: startsector=<Var/Sector>, jumps=<Var/Number>, owner=<Var/Race>
7.012 <RetVar/IF> = <RefObj> -> get ship array from sector/ship/station
7.013 <RetVar/IF> = <RefObj> -> get station array from sector
7.014 <RetVar/IF> = <RefObj> -> get factory array from sector
7.015 <RetVar/IF> = <RefObj> -> get dock array from sector
7.016 <RetVar/IF> = <RefObj> -> get player owned ship array from sector
7.017 <RetVar/IF> = <RefObj> -> get player owned station array from sector
7.018 <RetVar/IF> = <RefObj> -> get asteroid array from sector

Описание:

Возвращаемое значение (может являться аргументом для операторов IF, IF NOT, SKIP, WHILE, WHILE NOT)
Указатель на объект в отношении которого выполняется инструкция

Аргументы для команды или возвращаемые значения

Имя команды

Этим цветом выделен «@» флаг прерываемости команды


Работа с бортовым журналом

v Команды для работы с бортовым журналом.

write to player logbook <Value>

Записать значение <Value> в бортовой журнал игрока.

write to player logbook: printf: fmt=<Var/String>, <Value1>, <Value2>, <Value3>, < Value4>, <Value5>

Эта команда делает записывает в бортовой жернал, строку формата <Var/String>. Cтрокf формата <Var/String> может содержать в себе текст и спецсимволы вычисляемых значений (см. главу «Использование тегов и спец символов») которые заменяются соответствующими значениями Value. В одной строке формата может присутствовать до пяти вычисляемых значений

write to player logbook: printf: pageid=<Var/Number>, textid=<Var/Number>, <Value1>, <Value2>, < alue3>, <Value4>, <Value5>

Эта команда, то же делает запись в бортовом журнале, только текст строки формата берется из языкового файла со страницы pageid и текстового идентификатора textid. Текст строки формата может содержать и любые спецсимволы и теги.

<RefObj> write to logbook <Value>

Эта команда не используется.

write to log file = <Var/Number> append =< TRUE/FALSE > value=<Value>

write to log file = <Var/Number> append =< TRUE/FALSE > printf:fmt= <Var/String>, <Value>, <Value>, <Value>, <Value>, <Value>

write to log file = <Var/Number> append =<TRUE/FALSE> printf:pageid= <Var/String> textid=<Var/Namber>, <Value>, <Value>, <Value>, <Value>, <Value>

Действия всех трех команд анологичны родственным командам write to player logbook, только записи будут производится во внешний текстовый файл (txt) с именем LogNNNNN.txt, расположенном в главной папке игры. NNNNN это номер указанный в log file = <Var/Number>, в зависимости от параметра append [TRUE|FALSE] запись добавляется в конец файла (TRUE) или файл переписывается (FALSE). Использовать эти команды удобно при отладке скриптов или формировании внешних отчетов. Если при помощи данных команд формировать отчет, то не используйте в строке формата тэги и спецсимволы. В текстовом файле они отразятся как есть и не будут выполнять своих функций.


Навигационные команды

v Навигационные команды ( Fly commands ).

Большинство команд из семейства Fly to … выполняют в процессе исполнения комплекс одинаковых подготовительных или завершающих действий, ниже указана последовательность действий общих для этих команд:

  1. Отстыковаться (если пристыкован)
  2. Лететь в сектор, где находится объект назначения.
  3. Лететь к объекту.
  4. Пристыковаться (если требуется стыковка. Например fly to home base)

@<RetVar/IF> <ship> -> fly to home base

Дать команду объекту <ship> отстыковаться, лететь в сектор где находиться база к которой он приписан, и пристыковаться к ней.

Возвращает значения:

FLRET_LANDED | Команда выполнена корабль пристыкован.
FLRET_BREAK | Команда прервана другой командой Fly.
FLRET_INTERRUPTED | Команда прервана другим скриптом.
FLRET_ERROR | Ошибка при выполнении (например Нет базы приписки).

@<RetVar/IF> <ship> fly to station <Station>

Дать команду объекту <ship> «лететь на станцию» <Var/Station> и пристыковаться к ней.

Возвращает значения:

FLRET_LANDED | Команда выполнена корабль пристыкован.
FLRET_BREAK | Команда прервана другой командой Fly.
FLRET_INTERRUPTED | Команда прервана другим скриптом.
FLRET_ERROR | Ошибка при выполнении (например: база уничтожена)

@<RetVar/IF> <ship> fly to sector <Sector>

Дать команду объекту <RefObj> «лететь в сектор» <Var/Sector>.

FLRET_NOCOMMANDS | Команда выполнена корабль достиг сектора.
FLRET_BREAK | Команда прервана другой командой Fly.
FLRET_INTERRUPTED | Команда прервана другим скриптом.
FLRET_INVALIDPARMS | Если <RefObj> не существует.

* Если параметр <Var/Sector> не правильного формата (например просто число) то корабль отправиться в сектор Kingdom End.

<RetVar/IF> <object> find nearest enemy ship: max.dist=<distance>

Найти ближайший враждебный корабль и вернуть значение <RetVar/IF> в радиусе <distance> для объекта <object>.

<RetVar/IF> <object> find nearest enemy station: max.dist=<distance>

Найти ближайшую враждебную станцию и вернуть значение <RetVar/IF> в радиусе <Var/Number> для объекта <RefObj>.

<RetVar/IF> <object> fire lasers on target <target> using turret <turretid>

Дать команду <object> «стрелять лазерами» по цели <target> используя орудийную башню <turretid> . Если номер турели установлен как 0, то выстрел будет сделан из носового орудия, независимо от того находится цель target в зоне поражения или нет орудия все равно выстрелят и команда вернет [TRUE]. Если команда дана для выстрела именно из турели (номера больше 0), то следует позаботиться чтобы цель была в зоне видимости данной турели (именно видимости, точнее турель должна быть лицом к объекту), расстояние значения не имеет, если направленность правильная то будет сделан выстрел и функция вернет [TRUE]. В случае если цель вне зоны видимости, выстрела не произойдет и возвращаемое значение будет [FALSE].

В таблице указаны соответствующие номерам турели

0 | Центр (носовые)
1 | Носовая
2 | Кормовая
3 | Левая
4 | Правая
5 | Верхняя
6 | Нижняя

Возвращаемые значения: TRUE (1) или FALSE (null)

@<RetVar/IF> <object> turn turret <turretid> to target <target>: timeout=<timeout> ms

Дает команду объекту <object>, навести орудийную башню <turretid> на цель <target>. Исполнять команду не дольше <timeout> мс. Турель пытается найти цель в зоне своей видимости. Эта инструкция может быть использована при создании процедуры управляющей турелью.

Структура процедуры должна быть следующей:

  1. Определить объект для обстрела.
  2. Найти и навестись на объект.
  3. Если получен код FLRET_FIREFREE стрелять fire lasers on target.
  4. Повторяем снова со строки 2 пока, цель не сдастся, или не будет уничтожена.

Возвращаемые значения:

FLRET_FIREFREE | Команда выполнена турель наведена.
FLRET_TIMEOUT | Истекло указанное в timeout время.
FLRET_INTERRUPTED | Команда прервана другим скриптом.
FLRET_NOCOMMANDS | Ошибка. Неправильно указана турель, или объект.

Обратите внимание, что эта команда также как и fire lasers on target, не учитывает расстояния до цели, и может вернуть FLRET_FIREFREE даже если вы находитесь в сотне километров от нее.

@<RetVar/IF> <ship> attack run on target <target>: timeout=<timeout>ms

Команда «подготовить корабль к атаке» на цель <target>. Получив эту команду корабль <ship> совершает подготовительные действия, как то: взлет со станции, сближение с целью и т.д., в течении времени <timeout>.

Структура процедуры атаки:

  1. Определение объекта.
  2. Сближение с объектом.
  3. Подготовка к атаке attack run on target.
  4. Если FLRET_FIREFREE стреляем по цели fire lasers on target.
  5. Если цель жива переход к шагу 3.

Возвращаемые значения:

FLRET_FIREFREE | все готово для ведения огня по цели.
FLRET_TIMEOUT | Истекло указанное в timeout время.
FLRET_INTERRUPTED | Команда прервана другим скриптом.
FLRET_BREAK | Неверная цель. Цель не существует или не может быть атакована (цель находится в другом секторе, пристыкована к станции/транспорту и т.п.)
FLRET_NOCOMMANDS | Ошибка. Неправильно указан корабль <ship>.

@<RetVar/IF> <ship> defensive move: type= <type>, intensity=<intensity> timeout <timeout> ms, avoid object=<object>|null

Команда кораблю совершить маневр уклонения (резкие ускорения, спирали, изменение курса). Параметр type на сегодняшний день не реализован, тип маневра прописан непосредственно в движке программы. Параметр intensity указывается в процентах от 0 до 100 (фактически, если 0 то маневр будет заключаться, в прямом отлете на максимальной скорости исполняя «бочку». Если добавлять интенсивности, то к бочке будут добавляться периодические изменения курса.)

Возвращаемые значения:

FLRET_INTERRUPTED | Команда прервана другим скриптом.
FLRET_NOCOMMANDS | Маневр завершен, (вышло время timeout).
null | Если неправильно указан корабль <RefObj>

@<RetVar/IF> <ship> move to ware object <ware> for collecting: timeout=<timeout>ms

Команда кораблю, «лететь к плавающему в космосе контейнеру с целью подобрать». После завершения, корабль будет находиться на расстоянии позволяющем приступить к подбору летающего контейнера, или стрельбе по нему. В место контейнера можно указать и корабль, тогда наш корабль <ship> полетит к указанному кораблю и попытается занять место рядом с ним (100-300 метров).

Возвращаемые значения:

FLRET_FIREFREE | все готово занята позиция рядом с. <RefObj>
FLRET_TIMEOUT | Истекло указанное в timeout время.(не хватило времени)
FLRET_INTERRUPTED | Команда прервана другим скриптом.
FLRET_BREAK | Неверная цель. Цель не существует или находиться вне досягаемости (цель находится в другом секторе, пристыкована к станции/транспорту и т.п.)
FLRET_NOCOMMANDS | Ошибка. Неправильно указана объект <RefObj>.

<RetVar/IF> <ship> catch ware object <ware>

Подобрать плавающий в космосе контейнер. Получив эту инструкцию корабль подберет летающий в космосе контейнер <ware>. Инструкция не осуществляет ни каких действий над самим кораблем, все что произойдет, это указанный контейнер будет удален из сектора, а в трюм корабля <ship> добавиться количество товара находившиеся в этом контейнере. Расстояние инструкция не учитывает, подбор будет осуществлен даже если корабль находится в сотне километров от контейнера.

Возвращает [TRUE] если подбор контейнера осуществлен, [FALSE] если нет. Также возвращает [FALSE] если неправильно указать object <Value>, (корабль, станция и т.п.)

@<RetVar/IF> <ship> move around <timeout> ms

Фактическое назначение этой функции, это бесцельный полет по кругу в течении указанного времени (например корабли не имеющие задания). Корабль полетит со скоростью половина от максимальной. Если это корабль, на котором игрок, то корабль укорачиваться от препятствий не будет (может запросто с чем-нибудь столкнуться) и по истечении указанного времени будет продолжать полет. Если это другой корабль, то от препятствия отвернет в сторону и полетит уже в другом направлении. По истечении указанного времени остановится.

Возвращаемые значения:

FLRET_INVAIDPARMS | Неправильный объект <RefObj> (не корабль)
FLRET_NOCOMMANDS | Вышло время timeout, команда завершена

@<RetVar/IF> <ship> escort ship <target>

Команда кораблю <ship> сопровождать корабль (следовать за)<target>. Эта инструкция не имеет временного ограничения и будет выполняться до бесконечности. Корабль получивший эту инструкцию отстыкуется, если он пристыкован, и будет следовать за сопровождаемым кораблем в пределах сектора. Скорость корабля будет выровнена со скоростью сопровождаемого корабля. Если сопровождаемый корабль будет уничтожен, перейдет в другой сектор или пристыкуется к станции, то команда будет прервана и вернет код FLRET_BREAK. В случае прерывания команды другим скриптом, управление не будет передано этой команде даже после завершения скрипта, для возвращения управления команде escort ship используется команда set follow mode [FALSE], которая помещается перед escort ship. Режим сопровождения будет снова запущен, после возврата из прервавшего выполнение скрипта (return).

Возвращаемые значения:

FLRET_INTERRUPTED | Команда прервана другим скриптом.
FLRET_BREAK | Команда не может продолжить работу (сопровождаемый корабль покинул сектор, пристыковался к станции, уничтожен)
FLRET_INVAIDPARMS | Если неправильно указан корабль <RefObj>

@<RetVar/IF> <ship> escort ship <target>: timeout= <timeout>ms

Тоже команда эскортирования, действия единичны предыдущей разница заключается в том, что устанавливается временное ограничение на исполнение. И соответственно появляется еще один код возврата FLRET_TIMEOUT, время отведенное на выполнение вышло.

<ship> set formation <formation>

Установить тип построения <formation> для всех кораблей сопровождающих корабль <ship>. Тип постарения задает специальная константа Formation.<тип построения>.

[Formation.Delta] | 0 |
[Formation.Line] | 1 |
[Formation.X] | 2 |
[Formation.XDelta] | 3 |
[Formation.BigShipEscort] | 3 |
[Formation.Pyramid] | 4 |
[Formation.Random] | 5 | Случайное построение

<ship> add to formation with leader <leadership>

Добавить корабль <ship> в построение с ведущим кораблем <leadership>. Корабль займет место в построении сопровождающих <leadership> кораблей. Также для этого корабля станут доступны сигналы поступающие для всего построения, то есть корабль будет реагировать на изменение обстановки согласно поступившему сигналу (см. разд. SCE=> «Сигналы»).

<ship> remove from any formation

Исключить корабль<ship> из всех построений.

<RetVar/IF> <ship> get formation leader

Запрос типа построения. Запрос может относится к любому кораблю <ship> состоящему в построении.

Возвращает тип построения или null если корабль не участвует в построении.

<RetVar>=<ship> get formation follower ships

Возвращает массив кораблей участвующих в построении. Если указанное судно <ship> не является участником построения или не существует самого построения то команда вернет null.

START <object> command <Object Command>: arg1=<Value1>, arg2=<Value2>, arg3=<Value3>, arg4=<Value4>

Выполняет команду, как если бы игрок выбрал ее в командном меню. Возможность указать четыре аргумента, если они требуются.

<object> send signal <Object Signal>: arg1=<Value1>, arg2=<Value2>, arg3=<Value3>, arg4=<Value4>

Послать объекту <object> сигнал, то есть запустить на объекте обработчик посланного сигнала <Object Signal> (см. разд. SCE=> «Сигналы»).

@<RetVar/IF> <ship> follow object <target> with precision <precision> m

Дать команду кораблю <ship> следовать к кораблю <target> на расстояние <precision>. В отличии от команды escort ship предназначенной для сопровождения и защиты корабля, эта команда более удобна для подготовительных действий для нападения. То есть, для сближения с кораблем <target> на расстояние <precision>. Эта команда тоже запускает корабли если они пристыкованы, после этого корабль на максимальной скорости движется к цели. После достижения необходимого расстояния, команда возвращает код FLRET_TARGETREACHED (Обратите внимание на то, что выполнив команду корабль продолжит двигаться с максимальной скоростью. Так что, если вы поставите вслед за командой follow object команду wait с задержкой секунд 5, то корабль может улететь достаточно далеко от объекта, прежде чем продолжиться выполнение скрипта). Расстояние указывается приблизительно, т.к. добиться идеальной точности очень трудно, да и не к чему. Если выполнение команды прервано другим скриптом, то для возврата управления этой команде (после выполнения скрипта) нужно использовать команду set follow mode [FALSE].

До того как корабль достигнет нужного расстояния до цели, прервать выполнение команды может только другой скрипт или ситуация когда достижение цели становится невозможным (корабль-цель покинул сектор, пристыковался, уничтожен). Эта команда эффективна для преследования быстрых кораблей, если целью не является очень быстрым кораблем, то желательно использовать follow …timeout <…>.

Возвращаемые значения:

FLRET_TARGETREACHED | Цель достигнута, расстояние согласно precision
FLRET_INTERRUPTED | Команда прервана другим скриптом.
FLRET_BREAK | Команда не может продолжить работу (корабль-цель покинул сектор, пристыковался к станции, уничтожен)
FLRET_INVAIDPARMS | Если неправильно указан корабль <RefObj>

@<RetVar/IF> <ship> follow <target> with precision <precision> m: timeout=<timeout>ms

Та же команда «лететь к объекту», все функциональные действия как в предыдущей команде. Добавлен параметр timeout указывающий количество времени в миллисекундах на выполнение. Все возвращаемые коды те же, и добавлен еще FLRET_TIMEOUT (время отведенное на выполнение команды вышло)

<object> set follow mode [TRUE]|[FALSE]

Устанавливает включенным или выключенным (TRUE|FALSE) режим сопровождения. Фактически наличие этой команды перед follow или escort обеспечивает возврат управления этим командам после их прерывания. Управление возвращается после возвращения из прерывающего скрипта. В чем отличие между включенным и выключенным режимом непонятно. Похоже работают одинаково.

<RetVar/IF> <ship> get follow mode

Возвращает [TRUE] если корабль <ship> сопровождает или движется к объекту и [FALSE] если нет.

<ship> set destination to <destination>

Установить назначение. Фактически только информационная команда, чтобы игрок мог понять, куда корабль направляется, просмотрев информацию по кораблю. Непосредственно к полету команда не привязана, например можно командой fly to … послать корабль в одно место, а destination указать другое. Более подробное рассмотрение в разделе «Особенности использования некоторых команд.» глава «Использование информативных команд»

<RetVar/IF> <ship> get destination

Получить информативное назначение корабля <ship>, то есть значение установленное командой из командного меню или командой set destination.

<ship> set attack target to <target>

Устанавливает информативное значение <target> в пункте «Атаковать», учтите что <ship> должен выполнять команду которая активируем этот пункт в информационных экранах.

<RetVar/IF> <ship> get attack target

Возвращает информативное значение атакуемого объекта для корабля <ship>. Возвращаемое значение может быть установлено командой из командного меню или командой set attack target.

@<RetVar/IF> <ship> move to position: x=<xcoordinate> y=<ycoordinate> z=<zcoordinate> with precision <precision> m

Двигаться объекту <ship> в точку с указанными координатами до тех пор, пока удаленность <ship> от этой точки не станет менее "точности" <precision>. Эту удаленность(точность) требуется указывать именно в игровых юнитах, а не метрах, не смотря на наличие m после этого параметра. Т.е. желаемую удаленность требуется сначала умножить на 222, а потом подставлять в данную команду.

(akm) http://www.elite-games.ru/conference/viewtopic.php?p=640741#640741

<object> set command: <Object Command>

Суть этой команды в том, чтобы установить информационные значения, отображаемые в инфо-объекта и в меню собственности, для объекта <object> (работает только если <object>=[THIS]). Эта команда относится к семейству информативных команд, то есть ее цель только информация и ни какого отношения к управлению действиями объекта. Команда отразит в инфо-корабля напротив пункта «Команда» текст связанный с этой командой, взятый из основного языкового файла со страницы 2010. Этот текст будет отображаться все время выполнения скрипта или до другой команды set command. Если в процессе работы скрипт вызывает другой скрипт в котором присутствует команда set command изменяющая текущее значение, то по возвращению управления вызывающему скрипту, начальное значение set command восстановлено не будет. Подробно о информационных командах в разделе «Особенности использования некоторых команд.» глава «Использование информативных команд»

<RetVar/IF> <object> get command

Возвращает команду установленную для объекта <object>. Это может быть команда данная объекту из командного меню или установленная командой set command.

<object> set command target: <target>

Это тоже информативная команда, дополняющая команду set command. Set command target позволяет дополнить информацию выводимую предыдущей командой в пункте «Команда», указанием цели <target> для команды. Следует обратить внимание на то, что эта команда работает только со встроенными командами в ScE Х2. Если вы попробуете использовать ее со свободными командами типа CUSTOM, SPECIAL и т.п., то цель команды не будет отражена.

Команда имеет таки же ограничения как и set command. Значение устанавливается только на время выполнения скрипта.

<RetVar/IF> <object> get command target

Возвращает цель установленную для объекта. Это может быть значение задаваемое командой из командного меню объекта или командой set command target.

<object> set command target2: <target2>

Некоторые команды имеют второстепенную цель. Например, команда покупать товар имеет две цели. Первая, это товар который покупать, а второе это станция на которой покупать. Вот станция на которой корабль будет покупать товар и является target2. При помощи этой команды можно задать это значение.

Команда имеет те же ограничения, что и команда set command.

<RetVar/IF> <object> get command target2

Возвращает второстепенную цель объекта, заданную командой выбранной из командного меню или установленного командой set command target2.

<retvar>= <ship> -> select new formation leader by: ship class=

[TRUE]|[FALSE] strength=[TRUE]|[FALSE] min.speed=[TRUE]|

[FALSE]

Этой командой можно автоматически выбрать нового лидера для корабля <ship>, в случае уничтожения предыдущего – например, обработав сигнал SIGNAL_KILLED. Вы можете указать критерии по которым будет отбираться лидер. Выбор можно сделать по классу корабля, по силе корабля или по минимальной скорости. Например: имеется патрульный скрипт где патрулирование осуществляет группа кораблей разного класса. В бою лидер группировки был уничтожен, что бы выбрать для корабля нового лидера из кораблей

<RetVar/IF> = <ship> -> has formation ships

Возвращает [TRUE] если корабль <ship> имеет сопровождение, и [FALSE] если сопровождения нет.

<retvar>= <ship> -> give formation leadership to <newleader>

Эта инструкция позволяет изменить лидера группы. Возвращает [TRUE] если удалось и [FALSE] если нет.

<RefObj> set tactical to <Var/Number>

<RetVar>=<RefObj> get tactical

Не используются.

<RetVar/IF> get player tracking aim

Возвращает объект, который находится в прицеле корабля игрока. Вернет null, если в прицеле ничего нет.

<RetVar/IF> <ship> is <target> in firing range of turret <turretid>

Эта инструкция проверяет находится ли <target> в зоне поражения турели <turretid>. Проверяется расстояние до цели и дальность стрельбы из оружия установленного на указанной турели. Также можно использовать для определения находится ли цель в зоне поражения из основных орудий, достаточно указать turreted=0.

Возвращаемые значения [TRUE] если цель доступна и [FALSE] если нет.

<RetVar>=<ship> find enemy in firing range of turret <turretid>

Найти врага в зоне поражения указанной турели <turretid> корабля <ship>. Если цель находиться в зоне поражения турели (расстояние зависит от установленного оружия, если на турели не установлены пушки, то вернет null) то инструкция вернет значение [TRUE], если не одна цель не найдена вернет значение [FALSE]. Цель выбирается из установок корабля (свой-чужой), так что учтите что врагами могут оказаться и не враги. Например, в начале игры из-за недостатка рейтинга все их объекты сплитов отражаются как чужой (красный цвет) хотя сами по себе они нейтральны к игроку. Если использовать эту инструкцию, то все объекты сплитов будут оцениваться как враги.

<object> set command: <Object Command> target=<target1> target2=<target2> par1=<Value> par2=<Value>

Эта команда объединяет в себе целый набор информативных команд таких как set command и set target … target2 и позволяет задать еще два дополнительных параметра par1 и par2. Например команда GET_WARE помещает в дополнительные параметры количество покупаемого товара, и максимальную цену.

<RetVar/IF> <ship> fire missile <missile> on <target>

Команда для <ship> запустить 1 ракету типа <missile> в цель <target>. Ракеты должны быть в трюме, но устанавливать их не обязательно, выстрелит и так.

<RetVar/IF> <ship> get current missile

Возвращает тип активных в данный момент ракет для корабля <ship>. Если нет установленных ракет возвращает null.

<RetVar/IF> <ship> find best missile for target <value>

Возвращает тип ракеты из тех ракет, что есть в трюме <ship>, лучшую с точки зрения компьютера, для поражения цели <target>.

<RetVar> = best missile type for target <target>

Возвращает тип ракеты, которая по мнению компьютера, лучше всего подходит для поражения цели <Value>.

<RetVar/IF> <ship> launch <dronecount> fight drones: protect me or attack target=<target>

Команда запускает <dronecount> Дронов (если они есть в трюме <ship>) для защиты или атаки. Если установить <target> равным 0, дроны осуществляют защиту <ship>. Если <target> корабль, то дроны будут атаковать.

<RetVar/IF> <ship> is missile <missile> ready to fire

Возвращает [TRUE] если корабль <ship> готов к выстрелу ракетой <missile> (то есть ракеты имеются), и [FALSE] если нет.

<RetVar/IF> <ship> should a missile be fired

Возвращает [TRUE] если вероятность попадания ракеты по текущей цели высока и [FALSE] если вероятность низка. Команда просто делает анализ, наличие ракет значения не имеет. В основном альтернативой этой инструкции является инструкция check, select fire missile.

<RetVar>=<ship> get fire missile probability

Возвращает заданную в процентах вероятность пуска ракет для объекта <ship>.

<RetVar>=<RefObj> get fire missile time difference in seconds

<RefObj> set fire missile time difference to <time> s

???

<ship> set fire missile probability to <probability>

Устанавливает вероятность пуска ракет <probability> процентах, для объекта <ship>.

<RetVar/IF> <ship> fits laser <laser> into turret <turret>

Проверяет возможно ли установить пушку <laser> в турель с номером <turret> корабля <ship>. Если возможно - выдает [TRUE], если нет – [FALSE]. Проверяется только возможность установки, соответственно наличие самих пушек не нужно. Если установить turret 0, то проверится возможность установки пушек как носовых орудий.

<RetVar>=<ship> get max. number of lasers in turret <turret>

Получить число лазеров в турели <turret> корабля <ship>. Также, если установить turret=0, то вернет количество носовых орудий.

<RetVar>=<ship> get laser type in turret <turret> at slot <slot>

Возвращает тип пушки установленной на корабле <ship>, на турели <turret>, в слоте <slot>. Нумерация слотов начинается с 0 и идет слева на право. Например, если turret=0 slot=0, то инструкция вернет тип пушки левого носового орудия.

<RetVar>=<ship> get number of turrets

Возвращает количество турелей имеющихся на корабле <ship>. Носовые орудия тоже учитываются.

<RetVar>=get range of missile type <missile>

Возвращает радиус поражения (в метрах) ракеты типа <missile>.

<RetVar>=<ship> find nearest missile aiming to me

Инструкция осуществляет поиск ближайшей запущенной ракеты, наведённой на объект <object>. Данную инструкцию можно использовать только для поиска ракет. Возвращает указатель на ракету или null, если такой ракеты не найдено.

<RetVar/IF> <khaakship> decouple ships

Хаакский кластер <khaakship> после этой команды разваливается на отдельные корабли. Возвращает [TRUE] если кластер распался, [FALSE] если нет.

<RetVar/IF> <khaakship>is decoupled ships leader

Возвращает [TRUE] если хаакский корабль <khaakship> является лидером группы хаакских кораблей после распадения кластера и соответственно [FALSE] если нет.

<RetVar/IF> <ship>get current galaxy flight timestep in ms

Эта инструкция возвращает значение полетного таймстепа для сектора в котором находиться корабль <ship>. Таймстеп - это задержка между обновлениями ситуации в секторах. В секторе за которым идет наблюдение (просмотр карты сектора) таймстеп составляет 5000 миллисекунд, в других секторах (сектора за которыми в данное время нет наблюдения) таймстеп будет составлять 30000 миллисекунд.

<RetVar/IF> <ship>is landing

Эта инструкция проверяет, выполняет ли корабль в данный момент процедуру стыковку. Возвращаемые значения [TRUE] если корабль в данный момент стыкуется и [FALSE] если нет. Процедурой стыковки корабля считается завершающий момент (маневрирование перед входом в док и зам процесс входа), так называемая «завершающая стадия». Еще одна особенность это то, что если данная инструкция застанет корабль в момент входа во врата, то возвращаемое значение тоже будет [TRUE].

<RetVar/IF> <ship> is starting

Возвращает [TRUE] если корабль в данный момент взлетает со станции или носителя и [FALSE] если нет.

<RetVar/IF> <ship> use jump drive: target=<target>

Перемещение корабля с помощью прыжкового двигателя. <target> - это либо указатель на врата, либо на сектор. Если <target> – врата, то <ship> после прыжка появится из этих врат, если сектор, то появится в центре сектора. При выполнении этой команды на кораблях принадлежащих игроку, должен быть установлен прыжковый двигатель и в трюме должно быть необходимое для прыжка кол-во батареек. Для кораблей AL наличие прыжкового двигателя и батареек не обязательно.

Если требуется позиционировать прыжок в заданные координаты, то сразу после использования команды use jump drive следующей строкой должна идти команда set position с указанием необходимых координат. И обратите внимание, что для позиционированного прыжка, сам прыжок должен выполняться не во врата, а в центр сектора. Т.е. <target> для команды use jump drive должен быть сектор.

Команда возвращает один из двух FLRET кодов:

FLRET_WARPED | Прыжок совершен удачно
FLRET_ERROR | прыжок не удался (нет джампдрайва или батареек)

<RetVar/IF> <ship> needs jamp drive enerjy for jamp to:sector=<sector>

Возвращает количество батареек необходимых кораблю <ship>, для прыжка в сектор <sector>.

<RetVar/IF> <ship>check, select and fire missele on <target>

Эта комплексная команда для стрельбы ракетами, объединяющая в себе несколько функций. Выполняет следующие действия: проверяет доступна ли цель <target> для поражения ракетой, выбирает ракету, запускает ракету.

Возвращает [TRUE] если выстрел произведен, [FALSE] если нет.

<RetVar/IF> <object>add big ship <bigship>

Проверяет имеется ли техническая возможность у объекта <object> принять большой корабль (M6, M2, M1, TL). Имеется в виду рассчитан ли док корабля, на стыковку с большими кораблями.

<RetVar/IF> <object>has a free big ship dock slot

Возвращает [TRUE] если стыковочный док для больших кораблей объекта <object> свободен и может принять корабль, [FALSE] если нет.

<RetVar/IF> <object>can be controlled by race logic

Каждый созданный в игре объект не принадлежащий игроку, подключается ко встроенной логике расы владельца, которая и берет дальнейшее управление объектом в свои руки. Эта инструкция проверяет подключен ко встроенной расовой логике объект или нет.

Возвращаемые значения [TRUE] подключен, [FALSE] если нет.

<object>set race logic control enabled to [TRUE]|[FALSE]

При помощи этой инструкции можно подключить или отключить объект принадлежащий другой расе от встроенной расовой логики. Это удобно использовать для получения контроля над объектом в AL.plugin.

<RetVar/IF> <object>can execute StartAction

В ScE для каждого вновь созданного объекта предусмотрена команда которая дается объекту по умолчанию при его старте после создания, в отличии от расовой логики, стартовые действия объекта зависят только от его класса и расы владельца. В таблице указанны команды, которые получают вновь созданные корабли по умолчанию.

Класс | Игрок | Ксеноны, пираты, хааки |  | Остальные
M0 | COMMAND_KILL_ENEMIES
M1 | COMMAND_KILL_ENEMIES
M2 | COMMAND_KILL_ENEMIES
M6 | COMMAND_KILL_ENEMIES
M3 | COMMAND_NONE, если имеется лидер, то COMMAND_PROTECT (защищать лидера), если атакован то COMMAND_ATTACK (атаковать агрессора) |  | COMMAND_KILL_ENEMIES | COMMAND_RETURN_HOME
M4 | COMMAND_NONE, если имеется лидер, то COMMAND_PROTECT (защищать лидера), если атакован то COMMAND_ATTACK (атаковать агрессора) |  | COMMAND_KILL_ENEMIES | COMMAND_RETURN_HOME
M5 | COMMAND_NONE, если имеется лидер, то COMMAND_PROTECT (защищать лидера), если атакован то COMMAND_ATTACK (атаковать агрессора) |  | COMMAND_KILL_ENEMIES | COMMAND_RETURN_HOME
TS | COMMAND_NONE |  |  | COMMAND_DOCKAT приземлиться на ближайшей верфи
GO | COMMAND_NONE |  |  | COMMAND_PREACH
UFO | COMMAND_PREACH
SPACEFLY | COMMAND_FOLLOW
Все остальные | COMMAND_NONE

Эта команда возвращает получил ли новый объект стартовую команду. [TRUE] получил, [FALSE] нет.

<object> set StartAction enabled to [TRUE]|[FALSE]

Инструкция позволяет указать ScE следует или нет давать стартовую команду вновь созданному кораблю. [TRUE] вновь созданный объект получит стартовую команду, [FALSE] объект не получит никакой команды.

<ship>set as player wingman: [TRUE]|[FALSE]

Сделать корабль игрока ведущим для корабля <ship>. Рядом с именем корабля появиться значок «W». Корабль <ship> получит приказ защищать корабль игрока, и будет сопровождать вас везде, атаковать любых агрессоров, а также тех на кого нападете вы.

<RetVar/IF> <ship>is player wingman

Возвращает [TRUE] если корабль <ship> является ведомым для корабля игрока и соответственно [FALSE] если нет.


Работа с объектами

v Команды работы с объектами ( General object commands ).

<RetVar/IF> <object> get object class

Возвращает класс объекта <object> (схема классов в приложении «Иерархия объектов»).

<RetVar/IF> <object> get owner race

Возвращает расу владельца объекта <object>.

<RetVar/IF> <object> get environment

Возвращает окружение объекта <object>. Если объект пристыкован к станции или носителю, то инструкция вернет указатель на эту станцию или носитель, если объект находится в космосе, то вернет сектор в котором находиться объект.

<RetVar/IF> <object> get sector

Возвращает сектор, в котором находится объект <object>. Если объект пристыкован, то вернет сектор где находиться станция или носитель к которому пристыкован объект <object>.

<RetVar/IF> <ship> get homebase

Возвращает базу приписки корабля <ship> или null, если корабль не имеет приписки.

<RetVar/IF> <object> is of class <class>

Возвращает значение [TRUE], если объект <object> принадлежит к классу <class> и значение [FALSE], если нет. Эту инструкцию можно использовать для выбора объектов определенного класса. Например: корабль разведчик класса М3 войдя в сектор находит там вражеский корабль, нам требуется определить класс вражеского корабля для определения дальнейших действий разведчика. Если вражеский корабль является «Большим кораблем», то разведчик отступает.

…

056 if $enemy -> is of class Большой корабль

057 …процедура отступления…

… else

070 … процедура атаки…

… end

Иерархия классов объектов в приложении «Иерархия объектов».

<RetVar/IF> <object> exists

Возвращает значение [TRUE], если объект <object> существует, [FALSE] если нет. Помните, что игровая вселенная все время меняется, объекты с которыми обращается ваш скрипт могли быть уничтожены. При помощи этой инструкции вы легко можете проверить существует ли объект к которому вы обращаетесь:

…

040 skip if $object -> exists …если объект жив, то пропустить строку 041

041 return null … объект уничтожен. Выход из скрипта

… продолжение выполнения скрипта, если объект существует…

Всегда при создании скрипта, в самых первых строках, делайте проверку существования объекта с которым он должен работать. Это позволит избежать дальнейших ошибок.

<RetVar/IF> <object> get ware type code of object

Возвращает точный тип объекта. Результат данной функции можно, например, использовать, как аргумент для функции create, но учтите, содержит только тип объекта, так что вновь созданный объект не будет иметь апгрейдов установленных на <object>, их придется добавлять вручную, при помощи инструкции install и Add.

<RetVar/IF> <station> get serial name of station

Возвращает добавочный номер станции <object> в виде соответствующей ему буквы греческого алфавита (Альфа, Бета и т.д.). Эта инструкция не будет работать со станциями принадлежащими игроку. Описание греческого алфавита смотри в приложении Голосовые симплы.

<station> set serial name of station to <serial>

Устанавливает добавочный номер для станции в виде буквы греческого алфавита. Если использовать со станциями принадлежащими игроку, то работать не будет.

<RetVar/IF> find station in galaxy: startsector=<sector> class or type=<type> race=<race> flags=<flag> refobj=<object> serial=<serial> max.jumps=<maxjumps>

Инструкция для глобального поиска станции в галактике (не путайте с командами торгового поиска). Большинство параметров служат для уточнения параметров поиска. Все параметры кроме startsector и maxjumps могут быть установлены как null, что будет воспринято инструкцией как искать без ограничений по данному параметру. Например, если установить как null параметр race, то поиск будет производиться среди всех рас.

Используя инструкции глобального поиска в скриптах инициализации (имена Init. ), будьте осторожны и помните, что скрипты с именем init. загружаются до создания объектов в игровой галактике и инструкция почти наверняка вызовет зависание игры. Подробное описание всех параметров поиска в разделе «Особенности некоторых команд» глава «Организация глобального поиска объектов. Флаги поиска (Find)»

<RetVar/IF> <object> is of type <type>

Возвращает [TRUE], если объект <object> является указанным типом <type> (станцией или кораблем), иначе вернет [FALSE].

<RetVar/IF> get jumps from sector <startsector> to sector <endsector>

Возвращает количество прыжков от сектора <startsector> до сектора <endsector>.

<RetVar/IF> get next sector on route from sector <startsector> to sector <endsector>

Возвращает следующий сектор по пути следования из сектора <startsector> в сектор <endsector>.

<object> set homebase to <newhome>

Приписать объект <object> к станции или носителю <newhome>.

<RetVar/IF> <object> get current shield strength

Возвращает текущий уровень щита объекта <object> к килловатах.

<RetVar/IF> <object> get maximum shield strength

Возвращает максимальный уровень щита объекта <object> в киловаттах. Складывается из суммы мощностей всех щитов указанной в мегаваттах умноженной на 1000.

<RetVar/IF> <object> get current laser strength

Каждая пушка имеет установочный уровень огневой мощи, после каждого выстрела из пушки он уменьшается и на восстановление уходит некоторое время. Эта инструкция возвращает текущий уровень огневой мощи объекта <object>.

<RetVar/IF> <object> get maximum laser strength

Возвращает максимально возможный уровень огневой мощи объекта <object>. Складывается из суммы установочной огневой мощи всех установленных на объекте пушек.

<RetVar/IF> <object> get max. laser strength in turret <turret>

Возвращает максимальную огневую мощь турели <turret> установленной на объекте <object>. Складывается из суммы установочной огневой мощи всех пушек установленных на данной турели.

<RetVar/IF> <object> get max. shield type that can be installed

Возвращает максимальный тип щита (1, 5, 25, 125 Мвт), который можно установить на объект <object>. Все щиты совместимы по принципу уменьшения, т.е. если максимальный тип щита 25 Мвт, то вы можете установить на объект любой из щитов каких как 25, 5, 1 Мвт.

<RetVar/IF> <object> get number of shield bays

Возвращает количество слотов для установки щитов (количество щитов которое технически возможно установить) для объекта <object>. Общая мощность щитов объекта будет складываться из сумм установочной мощности всех установленных щитов.

<RetVar/IF> <object> get number of laser bays

Возвращает количество слотов для установки пушек для объекта <object>. Суммируются все слоты объекта (носовые орудия, турели).

<RetVar/IF> <object> get max. missile type that can be installed

Возвращает самый мощный тип ракет, который можно установить на объект <object>. Соответственно совместимы все ракеты меньшей мощности.

<RetVar/IF> <object> get relation to object <subject>

Возвращает отношение объекта <object> к объекту <subject>.

Возвращаемые значения:

Свой (Friendly) | Объекты принадлежащие собственной расе.
Нейтральный (Neutral) | Объекты принадлежащие другим расам не являющихся врагами.
Чужой (Enemy) | Объекты принадлежащие расе являющейся врагом

<RetVar/IF> <object> get relation to race <race>

Возвращает отношение объекта <object> к расе <race>. Возвращаемые значения: Свой (Friend), Нейтральный (Neutral), Чужой (Foe).

<RetVar/IF> <object> get notoriety to race <race>

<RetVar/IF> get notoriety from race <race> to race <anotherrace>

Не работает. Всегда возвращает ноль.

<RetVar/IF> <object> is <object> a enemy

<RetVar/IF> <object> is <object> a friend

<RetVar/IF> <object> is <object> neutral to me

Возвращает [TRUE], если объект является врагом\другом\нейтральным, в противном случае возвращает [FALSE].

<RetVar/IF> <object> get shield type in bay <slot>

Возвращает текущий тип щита, установленный в слоте <clot> (нумерация слотов с 0) объекта <object>.

<RetVar/IF> <object> get laser type in bay <slot>

Возвращает тип лазера установленного в слоте <slot> для объекта <object>. Нумерация слотов с 0, 0 – левое носовое орудие, 1- правое носовое орудие (если предусмотрено на данной модели корабля), далее идут слоты турелей.

<RetVar/IF> <object> has same environment as <subject>

Возвращает [TRUE] если <subject> находиться в той же среде, что и <object>. То есть, если и <object> и <subject> пристыкованы к одной станции или оба находятся в космосе в одном секторе. В противном случае инструкция вернет [FALSE].

<RetVar/IF> <object> is in same sector as <subject>

Возвращает [TRUE] если <subject> находиться в том же секторе, что и <object> и [FALSE] если нет. Также, можно использовать для проверки находиться ли объект в заданном секторе или нет (в космосе). Для этого <subject> должен являться указателем на сектор.

<RetVar/IF> <object> is landed

Возвращает [TRUE] если объект (должен принадлежать классу «Малые корабли») пристыкован к станции или носителю и [FALSE] если нет.

<RetVar/IF> <object> is docked

Возвращает [TRUE], если объект <object> находится в доке, это относиться как к объектам пристыкованым внутри станции, так и находящимся во внешнем доке (Большие корабли). В противном случае инструкция вернет [FALSE].

<RetVar/IF> <object> is docking possible of <ship>

Возвращает [TRUE], если корабль <ship> технически может пристыковаться к станции или носителю <object> (имеется ли стыковочный шлюз для больших кораблей) и [FALSE] если нет.

<RetVar/IF> <ship> is docking allowed at <target>

Возвращает [TRUE], если корабль <ship> теоретически был бы принят станцией или носителем, то есть проверка идет по двум условиям:

  1. <target> в принципе может принимать корабли (является станцией или носителем)
  2. <ship> не является врагом для <target>

Учтите, инструкция не проверяет технической возможности для стыковки (соответствия стыковочного дока размеру корабля, наличие в доке свободного места). [FALSE] возвращается в случае не соответствия любому из двух проверочных условий.

<RetVar/IF> <object> is in a sector

Возвращает [TRUE], если объект <object> не пристыкован к станции и находиться в секторе (в космосе).

<RetVar/IF> <object> get attacker

Если объект <object> подвергается нападению, то инструкция вернет указатель на агрессора. Если объект не атакуется, инструкция вернет null.

<object> -> set attacker to <attacker>

Устанавливает указатель на объект <attacker> как на агрессора в отношении <object>, то есть делает тоже самое, что произошло бы автоматически, если бы <attacker> начал стрелять по объекту <object>.

<retvar>= get distance between <oneobject> and <anotherobject>

Возвращает расстояние (в метрах) между двумя объектами. Инструкция работает с объектами находящимися в одном секторе.

<retvar>= <object> -> get distance to: x=<x> y=<y> z=<z>

Возвращает расстояние в метрах между объектом и указанными координатами.

<retvar>= <object> -> get distance to: position array=<position>

Возвращает расстояние в метрах между объектом и координатами записанными в массиве <position>. В массив содержит три числа, порядок чисел соответствует X, Y, Z.

<retvar>= <object> -> get distance: position array1=<position1> position array2=<position2>

Возвращает расстояние в метрах между двумя точками координаты которых хранятся в двух массивах. Массивы содержат по три числа, порядок чисел соответствует X, Y, Z.

<retvar>= create ship: type=<type> owner=<owner> addto=<target>

x=<x> y=<y> z=<z>

Инструкция создает новый корабль, с типом <type>, принадлежащий расе <race> по указанным пространственным координатам (указанных в метрах), в секторе указанном в параметре <target> (в случае если <target> - сектор). Если указать параметр <target> как станцию или носитель, то новый корабль будет добавлен непосредственно в док, а координаты проигнорированы. При размещении нового корабля по указанным координатам, эта инструкция осуществляет предварительную проверку заданных координат на наличие там других объектов и в случае, если место занято то новый корабль будет размещен в ближайшей безопасной точке пространства. Никогда создавайте корабль класса «Большой корабль» в доке станции, т.к. корабль будет помещен непосредственно внутрь и останется там навсегда, вылететь из стыковочного дока этот корабль никогда не сможет.

Параметр <type> может быть выбран из списка доступных кораблей, либо можно указать субтип корабля (посмотреть номер субтипа соответствующий требуемому кораблю можно в таблице в разделе «Приложение>Описание типов и субтипов” смотрите тип 7.) Соответственно команды :

$flag =  create ship: type=Argon Buster owner=Player addto=$sec x=$xcoord y=$ycoord z=$zcoord

и

$flag =  create ship: type=5 owner=Player addto=$sec x=$xcoord y=$ycoord z=$zcoord

создадут «Аргонский бастер».

Инструкция возвращает указатель на новый корабль, в случае если он был успешно создан. В противном случае вернет null.

<RetVar>=<object> get x position

<RetVar>=<object> get y position

<RetVar>=<object> get z position

Набор этих инструкций возвращает пространственную координату X, Y, Z (в метрах) для объекта <object>.

<RetVar>=<object> get position as array

Возвращает пространственную координату объекта <object> в виде массива, где координата по оси X индекс [0], Y индекс [1], Z индекс [2].

<RetVar>=get player ship

Возвращает указатель на корабль игрока, в исключительных случаях может вернуть null (у игрока нет корабля, возможно только в начале стандартной игры пока Бен Данна не дал игроку корабль или при использовании в инициализирующих скриптах, когда галактика еще не создана). Более удобная в использовании альтернатива данной инструкции, это константа [PLAYERSHIP].

<object> -> set relation against <target> to <relation>

Установить отношение <relation> объекта <object> к объекту <target>. Параметр <relation> может принимать одно из трех значений: Свой (Friendly), Нейтральный (Neutral), Чужой (Enemy).

<retvar>= create station: type=<type> owner=<owner>

addto=<sector> x=<x> y=<y> z=<z>

Создать новую станцию и добавить ее в сектор <sector> по указанным координатам. Параметр <type> указывает на то, что это за станция (выбирается из списка возможных). В параметре <owner> задается раса владелец станции. <sector>, <x>, <y>, <z> указывают сектор и координаты для размещения вновь созданной станции. Учтите, что эта инструкция не проверяет свободна ли точка по указанным координатами и в случае нахождения там какого либо объекта, он будет уничтожен.

Вновь созданная станция представляет из себя пустышку, т.е. для нее не установлены не выпускаемая продукция, не потребляемые ресурсы (команды add product/primary resource/ secondary resource). Так же, и сама станция не активирована (инструкция station trade and productions on). Для запуска станции необходимо произвести предварительные установки продукции и ресурсов и запустить процесс производства. Здесь вы вольны указать какой угодно вид продукции и используемых ресурсов, т.е. новая станция будет производить, то что вы ей укажите (add product), и из того, что будет установлено как первичные ресурсы (add primary resource).

В случае если станция удачно создана, инструкция вернет указатель на созданную станцию, если по каким либо причинам не удалось создать станцию, то вернет null.

<retvar>= create gate: type=<type> addto=<sector> gateid=<id>

dstsecx=<sectorx>
dstsecy=<sectory> dstgateid=<linkto>
x=<x>

y=<y> z=<z>

Создать врата и связать из с другим сектором. Параметр type указывает на тип врат Северные /North/ (0), Южные /South/ (1), Западные /West/ (2), Восточные /East/ (3). Gateid это специальный цифровой идентификатор врат, для встроенных в игру врат он совпадает с параметром type, задается в виде произвольного числа и служит для организации связи со вратами в другом секторе. Distsecx и Distsecy указывают соответственно на X и Y координаты сектора на карте галактики в который будет производится перемещение через новые врата. Далее следует идентификатор врат назначения, как уже говорилось он для встроенных в игру врат совпадает с «type», в случае если вы пытаетесь связать врата с вратами созданными вами, то укажите идентификатор который вы указывали при создании этих врат. Последние параметры «X» «Y» «Z» указывают координаты в секторе, где установить новые врата.

В случае если врата удачно созданы, инструкция вернет указатель на созданные врата, если по каким либо причинам не удалось создать врата, то вернет null.

<retvar>= create asteroid: type=<type> addto=<sector>

resource=<resource>
yield=<yield> x=<x>
y=<y> z=<z>

Создать новый астероид по указанным координатам в секторе <sector>. Параметр <type> указывает на визуальный образ астероида, всего в игре 10 возможных типов (визуальные образы смотри «Приложение=>типы астероидов»). Параметр ресурсы указывает на тип ресурсов содержащихся в новом астероиде:

Тип ресурсов | Наименование ресурса
0 | Железная руда (ore)
1 | Кремний (Silicon)
2 | Нивидиум (Nividium)

Параметр yield указывает на насыщенность ресурсом астероида, влияет на скорость добычи. Последние параметры «X» «Y» «Z» указывают координаты в секторе, где разместить созданный астероид. Эта инструкция как и create station не проверяет свободна ли точка по указанным координатам и в случае нахождения там какого либо объекта, он неминуемо будет уничтожен созданным астероидом.

В случае если атероид удачно создан, инструкция вернет указатель на созданный астероид, если по каким либо причинам не удалось создать врата, то вернет null.

<station> -> add product to factory or dock: <ware>

В игре, при создании станции инструкцией create station новая станция будет создана в виде пустышки. Это подразумевает что изначально, список производимой продукции и первичных и вторичных ресурсов будет пуст. При помощи этой инструкции можно добавить номенклатурную позицию продукции производимой станцией (указать продукцию которую будет производить станция). Вы можете установить для фабрики любую продукцию, она отобразиться в списке продукция, и после запуска производственного процесса начнет производится (при наличии ресурсов).

При помощи этой инструкции удобно добавлять новые позиции в доки и торговые станции. Но не забывайте, что эта команда не добавляет саму продукцию, а только номенклатурную позицию. Используйте для добавления самой продукции инструкцию add или наполняйте станции в игре при помощи транспортных кораблей.

<station> -> add primary resource to factory: <ware>

Добавить фабрике номенклатурную позицию первичных ресурсов <ware> объекту <station>. Принцип работы такой же, как инструкция add product.

<station> -> add second resource to factory: <ware>

Добавить фабрике номенклатурную позицию вторичных ресурсов <ware> объекту <station>. Принцип работы такой же, как инструкция add product. Станции игрока не используют вторичные ресурсы, т.е. в списке они отражаются и могут быть добавлены, но фабрика не будет им торговать или использовать их в производстве.

<station> -> remove product from factory or dock: <ware>

Удалить у фабрики или дока номенклатурную позицию из списка «Продукция». Вместе с номенклатурной позицией будет удален весь соответствующий ей товар находящийся на станции в данный момент.

<station> -> remove primary resource from factory: <ware>

Удалить у фабрики номенклатурную позицию первичный ресурс <ware> объекта <station>. Вместе с номенклатурной позицией будет удален весь соответствующий ей товар.

<station> -> remove second resource from factory: <ware>

Удалить у фабрики номенклатурную позицию вторичный ресурс <ware> объекта <station>. Вместе с номенклатурной позицией будет удален весь соответствующий ей товар.

<retvar>= create nebula: type=<type> addto=<sector> x=<x> y=<y> z=<z>

Создать туманность с типом <type> в секторе <sector> с указанными пространственными координатами X, Y, Z. Всего в игре существует 13 типов туманностей, которые могут быть созданы при помощи этой инструкции. Визуальные образы туманностей приведены в разделе «Приложение=>Описание туманностей»

<retvar>=
create sun: subtype=<subtype> r=<red>
g=<green> b=<blue>
addto=<sector> x=<x>
y=<y> z=<z>

Создать солнце с типом <subtype> в секторе <sector> по указанным пространственным координатам X, Y, Z. Параметры r, g, b не влияют на цвет самого солнца, они отвечают за насыщенность определенным цветом солнечного света ( r - красный, g – зеленый, b – синий), изменяется от 0 до 255. Визуальные образы соответствующие типам солнца приведены в приложении раздел Описание тиров солнц. Созданное солнце не является масштабируемым объектом, т.е. независимо от того находитесь вы в десяти километрах или в ста, размер солнца будет одинаков, вы можете разместить его в любой точке сектора.

<retvar>= create planet: subtype=<subtype> addto=<sector> x=<x>

y=<y> z=<z>

Создать планету с типом <subtype> в секторе <sector> по указанным пространственным координатам X, Y, Z. Создавая планету удаляйте ее минимум на 400 километров от центра цивилизации (скопления станций), иначе вы можете уничтожить всю жизнь в секторе раздавив их гравитационным полем планеты (этакая глобальная катастрофа). Визуальные образы планет в приложении «Описание типов планет».

<retvar>= create special: type=<type> addto=<sector> x=<x> y=<y> z=<z>

Создать специальный объект с типом <type> в секторе <sector> по указанным пространственным координатам X, Y, Z. При помощи этой инструкции создается все, что летает в космосе кроме объектов создаваемых инструкциями create planet|sun|nebula|station|ship|asteroid, т.е. обломки после разрушения станций, разрушенные врата, элементы кораблей и т.п. Всего существует 73 специальных объекта и учтите, что на многие спец.объекты гравилокатор корабля не реагирует.

Описание типов спец.объектов в приложении «Описание спец.объектов».

<retvar>=
find ship: sector=<sector> class or type=<classtype>
race=<race> flags=<flags>
refobj=<refobj> maxdist=<maxdist>
maxnum=<maxnum> refpos=<position>

Найти указанное количество <maxnum> (при установленном флаге [Find.Multiple]) кораблей класса или типа <classtype> в секторе <sector> расы <race>, максимальное расстояние поиска <maxdist>. Использование флагов поиска описано в разделе «Организация глобального поиска объектов. Флаги поиска (Find)» Параметры classtype, race могут быть установлены как null, для поиска без ограничений по этим параметрам. Параметр refpos представляет из себя массив содержащий координаты точки в секторе X, Y, Z и указывает на точку в секторе от которой будет вестись поиск. Параметр refobj указывает на объект от которого будет производиться поиск. При организации поиска допускается использование какого-то одного параметра, либо refpos либо refobj (не используемый должен быть установлен как null)

Возвращает найденный корабль или массив кораблей, если подходящих кораблей не найдено возвращает null.

<retvar>= find asteroid: sector=<sector> resourcetype=<resource> min. yield=<yield> flags=<flags> refobj=<refobj> maxdist=<maxdist> maxnum=<maxnum> refpos=<position>

Найти указанное количество <maxnum> (при установленном флаге [Find.Multiple]) астероидов с типом ресурсов <resourse> (0 – руда, 1 – кремний, 2 – нивидиум) в секторе <sector> насыщенность не менее <yield>, максимальное расстояние поиска <maxdist>. Использование флагов поиска описано в разделе «Организация глобального поиска объектов. Флаги поиска (Find)». Параметр refpos представляет из себя массив содержащий координаты точки в секторе X, Y, Z и указывает на точку в секторе от которой будет вестись поиск. Параметр refobj указывает на объект от которого будет производиться поиск. При организации поиска допускается использование какого-то одного параметра, либо refpos либо refobj (не используемый должен быть установлен как null)

Возвращает найденный астероид или массив астероидов, если подходящих астероидов не найдено возвращает null.

<retvar>=
find flying ware: sector=<sector> maintype=<maintype>
subtype=<subtype> flags=<flags>
refobj=<refobj> maxdist=<maxdist>
maxnum=<maxnum> refpos=<position>

Найти указанное количество <maxnum> (при установленном флаге [Find.Multiple]) контейнеров с товаром летающих в космосе в секторе <sector>. Все товары в Х2 разделены на группы maintype и подгруппы subtype, вы можете установить поиск по обоим этим параметрам или по одному из них (неиспользуемый установить как null) Максимальное расстояние поиска <maxdist>. Использование флагов поиска описано в разделе «Организация глобального поиска объектов. Флаги поиска (Find)». Параметр refpos представляет из себя массив содержащий координаты точки в секторе X, Y, Z и указывает на точку в секторе от которой будет вестись поиск. Параметр refobj указывает на объект от которого будет производиться поиск. При организации поиска допускается использование какого-то одного параметра, либо refpos либо refobj (не используемый должен быть установлен как null)

Возвращает найденный контейнер с товаром или массив контейнеров, если подходящих контейнеров не найдено возвращает null.

<retvar>=
find station: sector=<sector> class or type=<classtype>
race=<race> flags=<flags>
refobj=<refobj> maxdist=<maxdist>
maxnum=<maxnum> refpos=<position>

Инструкция для поиска станции или станций. По работе похожа на инструкцию find station in galaxy, отличие в том, что эта инструкция ищет станцию в пределах указанного сектора, кроме того эта инструкция может возвращать массив станций при установленном флаге [Find.Multiple], количество искомых станций указывается в параметре maxnum. Все параметры как у предыдущих инструкций поиска.

<RetVar/IF> <spacefly> is disabled

Эта инструкция предназначена для работы с объектами класса «SpaceFly» (космомуха) и возвращает значение [TRUE]|[FALSE] в зависимости от того активна муха или нет. Это подразумевает под собой следующее: в игре вы можете на некоторое время оглушить муху при помощи Ion Disruptor, так вот при помощи этой инструкции можно определить в активном состоянии муха или оглушена. Инструкция работает только с объектами «SpaceFly».

Возвращаемые значения [TRUE] если муха находиться в оглушенном состоянии или [FALSE] если муха активна.

<object> -> station trade and production tasks: on=[TRUE]|[FALSE]

Эта команда предназначена для запуска (TRUE) или остановки (FALSE) процесса производства на фабриках. Основное применение, это все таки, запуск процесса производства на вновь созданных станциях (инструкцией create station). После создания, новая фабрика не имеет установленных ресурсов, а также не установлена и производимая продукция. Перед стартом производственного процесса необходимо произвести установку производимой продукции и используемых ресурсов (инструкции add product, add primary/secondary resource), и запустить производственный процесс. Если этого не сделать, то даже после доставки на станцию необходимого количества ресурсов производство не начнется. И указатели количества ресурсов необходимых для одного цикла (значение в квадратных скобках, под шкалой количества ресурсов на станции) и количества ресурсов производимых за один цикл будут показывать ноль. Запустив данную команду со значением TRUE, вы запустите процесс и начнется переработка, указатели установятся на нужные значения. Обратите внимание на то, что если на станции нет необходимого количества ресурсов, а процесс производства запущен, то после их доставки производство может начаться не сразу, а спустя пару минут.

<RetVar/IF> = <object> -> get SectorObject ID

Возвращает секторный идентификатор объекта <object>. Данный идентификатор получают только те объекты, которые находятся в одном секторе с кораблем игрока. Вообще в Х2 секторальными объектами являются совершенно все объекты находящиеся в секторе с кораблем игрока, также сам сектор является объектом имеющим ID. Фактически это визуальные модели объектов, то есть в момент входа корабля игрока в сектор, происходит формирование ID сектора, затем для солнц, туманностей, станций, кораблей и астероидов (создается сам визуальный образ сектора и каждый объект получает свой номер). После выхода корабля из сектора все ID удаляются и создаются для следующего сектора в который вошел игрок.

<RetVar>= <object> -> get ware type of SectorObject <sectorobject>

Возвращает тип товара связанного с объектом имеющим с идентификатором <sectorobject>.

<RetVar/IF> exists SectorObject <sectorobject>

Возвращает [TRUE], если объект с идентификатором <sectorobject> существует и [FALSE] если объект не существует.

<RetVar/IF> get object from SectorObject <sectorobject>

Возвращает нормальный указатель на объект по соответствующему ID. Если вернуть указатель невозможно (объект уничтожен, неправильный ID) вернет null.

<object> destruct: show no explosion=[TRUE]|[FALSE]

Уничтожает объект <object>. Параметр explosion указывает, показывать взрыв [TRUE] или нет [FALSE].

<object> -> set position: x=<x> y=<y> z=<z>

Переместить объект <object> в точку пространства с указанными координатами X, Y, Z. Будьте аккуратны используя эту инструкцию, она не делает проверки находиться ли по этим координатам какой либо объект. И соответственно если по этим координатам будет находится, например станция, а вы поместите туда корабль, то он разобьется о корпус станции.

<object> -> set rotation: alpha=<alpha> beta=<beta> gamma=<gamma>

Получает/устанавливает угол поворота объекта в системе координат X2

alpha - угол поворота в плоскости XZ (карта X2), направление на N = 0, W = 16384,S = 32768,E = -16384 = (32768+16384)

beta - угол подъема вектора корабля от плоскости XZ (тангаж), 0 - вектор в плоскости XZ, 16384 - нормаль XZ (параллелен оси Y) и т.д.

gamma - крен корабля - угол поворота плоскости корабля относительно положения вектора, заданного alpha и beta; определяет не столько ориентацию вектора, сколько способ модификации alpha и beta при управлении (изменяется клавишами <Q>,<W>), задается также в системе [-0xFFFF..0xFFFF] (65536), c направлением против часовой стрелке

set position of sector object <sectorobject>: x=<x> y=<y> z=<z>

Переместить объект <sectorobject> в точку пространства с указанными координатами X, Y, Z и вернуть указатель на этот объект. Тоже самое, что и set position, только работает с секторным ID.

set safe position of sector object <sectorobject>: x=<x> y=<y> z=<z>

Переместить объект с идентификатором <sectorobject> в точку пространства с указанными координатами X, Y, Z и вернуть указатель на этот объект. В отличии от предыдущей инструкции осуществляет проверку точки с заданными координатами на наличие там других объектов. В случае, если по указанным координатам находиться другой объект, то перемещаемый объект будет помещен в ближайшую свободную точку.

set rotation of sector object <sectorobject>: alpha=<alpha> beta=<beta> gamma=<gamma>

Установить углы вращения альфа, бета и гамма объекта <sectorobject>. Выполняет те же действия, что и предыдущая инструкция set rotation, только работает и ID объекта.

<retvar>= create sector object: maintype=<maintype> subtype=<subtype>

Разместить в памяти секторный объект с типом <maintype> и подтипом <subtype>. Модель объекта будет загружена в память, но в пространстве сектора новый объект не появится (т.е. визуальная модель объекта не будет отображена) до момента запуска объекта выполняемого инструкцией start sector object. Однако ScE будет считать, что объект присутствует в секторе.

Все инструкции для работы с секторальными объектами относятся к инструкциям низкого уровня, что подразумевает под собой низкоуровневое обращение к ScE. Используя эти инструкции можно легко повредить сейв-файл (сейв с неправильно созданными секторальными объектами не будет загружаться) или подвесить игру. В связи с этим старайтесь заменять эти инструкции инструкциями более высокого уровня, например вместо данной инструкции лучше использовать инструкции типа create ship|station|sun и т.д.

free sector object <sectorobject>

Удалить из сектора визуальную модель объекта с идентификатором <sectorobject>, все ссылки на объект остаются удаляется только модель, т.е. ScE считает, что объект находиться в секторе, так же он присутствует в списке объектов и на карте сектора.

Все инструкции для работы с секторальными объектами относятся к инструкциям низкого уровня, что подразумевает под собой низкоуровневое обращение к ScE. Используя эти инструкции можно легко повредить сейв-файл (сейв с неправильно созданными секторальными объектами не будет загружаться) или подвесить игру. В связи с этим старайтесь заменять эти инструкции инструкциями более высокого уровня, например вместо данной инструкции лучше использовать инструкции типа destruct ship|station|sun и т.д.

kill sector object <victim>: reason <reason>, killer sector object <killer>

Инструкция сообщающая ScE о том, что секторальный объект с ID <victim> уничтожен секторальным объектом имеющим ID <killer>, уничтожение произошло в следствии одной из трех причин указанных в параметре <reason>.

Код причины уничтожения | Описание
2 | Выстрел из пушки
3 | Столкновение
5 | Попадание ракетой

ScE в свою очередь запускает стандартную процедуру уничтожения, т.е. взрыв и удаление объекта <victim> и всех ссылок на него.

start sector object <sectorobject> in space <sectorid>

Разместить в пространстве сектора с идентификатором <sectorid>, визуальную модель секторального объекта имеющего ID <sectorobject>, ранее созданного инструкцией create sector object .

Все инструкции для работы с секторальными объектами относятся к инструкциям низкого уровня, что подразумевает под собой низкоуровневое обращение к ScE. Используя эти инструкции можно легко повредить сейв-файл (сейв с неправильно созданными секторальными объектами не будет загружаться) или подвесить игру. В связи с этим старайтесь заменять эти инструкции инструкциями более высокого уровня, например вместо данной инструкции лучше использовать инструкции типа create ship|station|sun и т.д.

<retvar>=
create flying ware: maintype=<maintype>
subtype=<subtype> count=<count>
sector=<sector> x=<x>
y=<y> z=<z>
selfdestruct= <timedestruct>

Создать контейнер в пространстве сектора с товаром в количестве <count> с типом <maintype> и подтипом <subtype> в секторе <sector> в точке с указанными пространственными координатами X, Y, Z и временем самоуничтожения <timedestruct> указанном в миллисекундах. Перед размещением контейнера инструкция проверит точку по указанным координатам и в случае нахождения там какого либо объекта разместит контейнер в ближайшей свободной точке. Параметр selfdestruct устанавливает время в течении которого контейнер будет находится в космосе (от момента создания), по истечении заданного времени контейнер самоуничтожится. Если же, в этом параметре поставить значение null, то контейнер будет существовать неограниченно долго.

Возвращает указатель на созданный контейнер, в случае если контейнер удачно создан или null если не удалось создать контейнер.

<RetVar>=<object> get rot alpha

<RetVar>=<object> get rot beta

<RetVar>=<object> get rot gamma

Возвращает текущую ориентацию объекта в пространстве, соответственно углы:

alpha - угол поворота в плоскости XZ (карта X2), направление на N = 0, W = 16384,S = 32768,E = -16384 = (32768+16384)

beta - угол подъема вектора корабля от плоскости XZ (тангаж), 0 - вектор в плоскости XZ, 16384 - нормаль XZ (параллелен оси Y) и т.д.

gamma - крен объекта- угол поворота плоскости корабля относительно положения вектора, заданного alpha и beta; определяет не столько ориентацию вектора, сколько способ модификации alpha и beta при управлении (изменяется клавишами <Q>,<W>), задается также в системе [-0xFFFF..0xFFFF] (65536), c направлением против часовой стрелке

<RetVar>=<object> get size of object

Возвращает размер объекта пространстве. Представляет из себя радиус воображаемой сферы, созданной вокруг объекта. Значение возвращается в юнитах, для перевода в метры разделите значение на 222.

<RetVar/IF> <object> get max upgrades for upgrade <ware>

Возвращает максимальное кол-во апгрейдов <ware>, которые можно установить на <object>.

<RetVar/IF> <object> get max speed

Возвращает максимальную скорость объекта без апгрейдов. Возвращаемое значение в игровых юнитах, для перевода в м/с разделите значение на 222.

Вот как можно "добыть" реальную макс. скорость корабля $Ship с учетом его текущих апгрейдов:

$speed = $Ship -> get max speed

$engine.upgrades = $Ship -> get amount of ware Engine Tuning in cargo bay

$speed = $speed * [ 10 + $engine.upgrades ] / 10

Получившаяся скорость $speed будет в игровых юнитах. Если желаете перевести ее в м/с, то $speed надо разделить на 222

<RetVar/IF> <object> get max hull

Получить максимальную величину корпуса <object>.

<RetVar/IF> <object> get hull

Получить текущую величину корпуса <object>, с учетом нанесенных повреждений.

<RetVar/IF> <object> get hull percent

Получить текущую величину корпуса <object> в процентах от максимального значения. Возвращается число от 0 до 100.

<RetVar/IF> <object> get shield percent

Получить текущую величину щита <object> в процентах. Возвращается число от 0 до 100.

<RetVar/IF> <object> get shield and hull percent

Должна возвращать массив из двух значений, состояние щита и состояние корпуса в процентах от максимального. Но фактически возвращает только состояние щита и то как то не правильно. В общем судя по всему инструкция не работает.

<RetVar/IF> <object> get max upgraded speed

Возвращаем максимальную скорость объекта при установленных полностью апгрейдах двигателей. Значение возвращается в юнитах, для перевода в метры разделите значение на 222. Обратите внимание на то, что возвращается максимальная скорость при максимальном количестве апгрейдов прописанном для корабле в самой игре, т.е. так называемое паспортное значение. Это означает что если вы используете какой либо скрипт увеличивающий скорость корабля, за счет добавления лишних апргрейдов двигателя, то эта инструкция не будет их учитывать.

<RetVar/IF> <object> get dock bay size

Возвращает максимальное количество кораблей, которые могут быть одновременно пристыкованы к объекту. Для станций это значение равно одному миллиону.

<RetVar/IF> <object> get number of landed ships

Возвращает количество кораблей пристыкованых в данный момент к объекту.

Player loses police licence for race <race>

Лишить игрока полицейской лицензии выданной расой <race>.

<race> -> add notoriety: race=<subject> value=<value>

Добавить репутацию расе <subject> у расы <race> на <value> единиц. Значение <value> прибавляется к текущему значению репутации, если использовать отрицательное число, то значение соответственно отнимается и репутация уменьшается.

<spacefly>set ship disabled to [TRUE]|[FALSE]

Эта инструкция предназначена для работы с объектами класса «SpaceFly» (космомуха). При помощи этой инструкции можно деактивировать муху, т.е. оглушить ее (эффект выстрела из Ion Distruptor) значение [TRUE] или наоборот вывести ее из оглушенного состояния значение [FALSE]. Инструкция работает только с объектами «SpaceFly».

<object>put into environment <environment>

Поместить корабль в определенное окружение <environment>. Не путайте эту команду с навигационной командой fly to, т.к. эта инструкция просто перемещает объект в указанную среду. Средой для перемещения может являться сектор или станция, а объектом корабль. Будьте осторожны при работе с большими кораблями, их при помощи этой команды можно перемещать только в сектор, т.к. перемещаемый корабль помещается непосредственно в стыковочный док, а не в шлюз (то есть, внутрь станции). Если вы все таки попробуете переместить большой корабль на станцию, то перемещение произойдет, но корабль никогда не сможет взлететь со станции. При перемещении объекта в сектор, он появиться по координатам в которых он находился в предыдущем секторе.

Обратите внимание на то, что эта команда не запускает механизма создания секторальных объектов (генерации 3D-объектов), из чего следует – нельзя применять эту команду к кораблю игрока, т.к. теоретически перемещение произойдет и все внутренние ссылки на Playership будут изменены, а визуальные 3D-модели сектора-назначения и всех находящихся в нем объектов созданы не будут (вокруг будет чернота, но на карте сектора ваш корабль будет присутствовать – и соответственно может быть убит кем нибудь), то есть ScE считает, что корабль игрока находиться внутри сектора, а сектор система будет считать удаленным.

<station> station send defend squad against ship <target>

Команда станции выслать корабли охраны (все корабли класса "истребитель", которые приписаны к этой станции, если каковые имеются) для атаки <target>.

<RetVar>= <object> get name

Возвращает строку имя обекта <object> в переменную <RetVar>

<object> set name to <name>

Установить объекту <object> имя указанное в строке <name>

<object> set owner race to <race>

Назначить объекту <object> владельцем расу <race>. Объектом может быть станция, корабль все что имеет расовую принадлежность. По-идее можно использовать для эмуляции захвата. Однако если таким образом захватывать станцию, следует позаботиться о приписанных к станции кораблях, т.к. после изменения расы владельца, приписанные корабли по прежнему будут считать эту станцию базой приписки, несмотря на то, что база принадлежит теперь другой расе.

<retvar>=
<object> -> find ship: class or type=<classtype>
race=<race> flags=<flags>
refobj=<refobj> maxdist=<maxdist>
maxnum=<maxnum> with homebase=<homebase>

Возвращает массив кораблей, находящихся на/в <object> в секторе <sector> имеющих расу "race", у которых база приписки "homebase", отсортированных и выбранных в соответствии с параметрами "flags" и объектом "refobj". Максимальное количество кораблей в возвращаемом массиве определяется параметром "maxnum".

Имейте ввиду, что в качестве "race" допустимо лишь указание конкретных рас или null (что означает любая раса). Для поиска врагов/нейтральных/друзей используйте соответствующие флаги и указывайте в качестве "refobj" объект по отношению к которому и будут определяться враг/друг.

А вот <object> должен быть либо сектором, либо станцией, либо кэрриером. В противном случае команда вернет null.

Обратите внимание на то, что абсолютно все команды поиска кораблей в секторе, никогда не возвращают корабли, пристыкованные к чему-либо, даже если эти корабли находятся в этом секторе!

<retvar>=
find station in galaxy: startsector=<sector> class or type=<type>
race=<race> flags=<flags>
refobj=<object> serial=<serial>
maxjumps=<maxjumps> num=<count>

Это второй вариант инструкции поиска станции в галактике find station in galaxy, с тем отличием, что эта инструкция возвращает массив из найденных станций. Максимальное количество станций указывается в параметре num, не используйте в этом параметре null, а то инструкция вернет null.

<RetVar>= <object> get ID code

Возвращает ID код данного объекта, не путайте с ID секторального объекта. ID код – это специальный оригинальный номер объекта состоящий из цифрового индекса в котором зашифрованы следующие данные:

1. для объектов имеющих принадлежность - принадлежность объекта, его класс и номер (например: случайного Аргонского транспорта класса ТХ – ID ATXRF-83) Первая буква индекс расы владельца. Две следующих класс объекта. Остальные код и номер.

2. для объектов не имеющих принадлежности (врат, астероиды и т.п.) код короче на один символ . Для врат, первые две буквы обозначают расположение врат (SO – Южные, WE – Западные, EA – Восточные, NO – Северные). Для прочих объектов первые две буквы, это тип объекта. Для астероидов, контейнеров и т.п. первые два символа тип объекта.

<RetVar>= <ship> get pilot name

Возвращает имя пилота корабля <ship> как строку. Если корабль принадлежит игроку, то возвращается имя игрока.

<ship> set pilot name to <string>

Изменить имя пилота корабля <ship> на имя указанное в строке <string>. Эта инструкция ничего не изменит, если выбран корабль принадлежащий игроку.

<ship> -> set pilot speaker: voice=<voice>, face=<face>, Pirate subrace=<race>, Argon female=[TRUE]|[FALSE]

Установить тип голоса пилота корабля <ship> в <voice>, тип лица пилота в <face>, расу пилота race (если это пират, если нет устанавливается значение null), а также признак "женский голос" если пилот - женщина расы Аргон. Типы лиц описаны в приложении «Визуальные образы пилотов». При параметрах voice и face равном 0, будет установлен тип лица и голоса пилота заданный данному короблю ScE при создании.


Торговые команды

v Торговые команды ( Trade commands ).

<RetVar/IF> get player money

Возвращает сумму денег на счету игрока.

add money to player: <amount>

Добавить на счет игрока сумму денег <amount>, если значение <amount> отрицательное, то списать со счета эту сумму.

<RetVar/IF> <object> add <amount> units of <ware>

Добавить в трюм объекта <object> указанное количество <amount> товара <ware>. Добавляемые товары помещаются непосредственно в трюм объекта, если указанное количество товара больше свободного места в трюме объекта, то будет добавлено столько товара сколько войдет. Товар помещается в трюм, соответственно если при помощи этой инструкции добавить пушку или щит, то они не будет установлены, а будут лежать в трюме объекта. Указав отрицательное число в параметре <amount> можно удалить это количество товара из трюма. Эта инструкция возвращает количество добавленного или удаленного товара, если указанный товар невозможно поместить в трюм объекта вернет 0, а товар добавлен не будет.

<RetVar/IF> <object> install <amount> units of <ware>

Установить заданное количество <amount> товара <ware> на объект <object>. Эта инструкция предназначена для установки на объект оборудования и апгрейдов. Так же, при ее помощи можно добавить и товар как add. При использовании отрицательного числа, как и предыдущая инструкция, удаляет определенное количество апгрейдов или товара. Возвращает количество установленного или удаленного товара, апгрейда.

<RetVar>=get volume of ware <ware>

Возвращает количество места занимаемого в трюме одной единицей товара <ware>.

<RetVar>=get transport class of ware <ware>

Возвращает класс транспортного контейнера для товара <ware>.

Tiny Containers | Микроконтейнеры
Small Containers S | Малые контейнеры S
Medium Containers M | Средние контейнеры M
Large Containers L | Большие контейнеры L
Extra Large Containers XL | Сверхбольшие контейнеры XL
Station Containers ST | Станционные контейнеры ST

<RetVar/IF> find station: product <product> with best price: max.price=<price>, amount=<amount>, max.jumps=<jumps>, startsector=<sector>, trader=<trader>

Найти станцию производителя товара <ware> с наилучшей ценой. Максимальная цена на товар <price>, количество товара на станции не меньше <amount>, прыжков до станции не больше <jumps>, начиная с сектора <sector>, которая может торговать с кораблем/станцией <trader> (подразумевается, что объект не является врагом и имеет доступ на станцию). Обратите внимание на следующий момент, при помощи этой инструкции нельзя найти верфь продающую какой либо корабль или станцию, эта инструкция рассчитана на поиск только товаров класс контейнера которых не более XL и апгрейдов.

Возвращает в <RetVar> указатель на станцию если она найдена, null если станции соответствующей условиям поиска нет.

<RetVar/IF> find station: product <product> with min. jumps: max.price=<price>, amount=<amount>, max.jumps=<jumps>, startsector=<sector>, trader=<trader>

Найти станцию производителя товара <ware> с минимальным количеством прыжков до неё. Максимальная цена на товар <price>, количество товара на станции не меньше <amount>, прыжков до станции не больше <jumps>, начиная с сектора <sector>, которая может торговать с кораблем/станцией <trader>. Обратите внимание на следующий момент, при помощи этой инструкции нельзя найти верфь продающую какой либо корабль или станцию, эта инструкция рассчитана на поиск только товаров класс контейнера которых не более XL и апгрейдов.

Возвращает в <RetVar> указатель на станцию если она найдена, null если станции соответствующей условиям поиска нет.

<RetVar/IF> find station: resource <product> with best price: max.price=<price>, amount=<amount>, max.jumps=<jumps>, startsector=<sector>, trader=<trader>

Найти станцию покупателя товара <ware> по наилучшей цене. Максимальная цена на товар =<price>, потребность в товаре не менее <amount>, прыжков до станции не больше <jumps>, начиная с сектора <sector>, которая может торговать с кораблем/станцией <trader>.

Возвращает в <RetVar> указатель на станцию если она найдена, null если станции соответствующей условиям поиска нет.

<RetVar/IF> find station: resource <product> with min. jumps: max.price=<price>, amount=<amount>, max.jumps=<jumps>, startsector=<sector>, trader=<trader>

Найти станцию покупателя товара <ware> с минимальным количеством прыжков до неё. Максимальная цена на товар =<price>, потребность в товаре не менее <amount>, прыжков до станции не больше <jumps>, начиная с сектора <sector>, которая может торговать с кораблем/станцией <trader>.

Возвращает в <RetVar> указатель на станцию если она найдена, null если станции соответствующей условиям поиска нет.

<RetVar/IF> find station sell: resource <product> with best price: max.price=<price>, amount=<amount>, max.jumps=<jumps>, startsector=<sector>, trader=<trader>

Найти станцию продающею товар <product>, по наилучшей цене. Инструкция будет искать торговые станции или доки оборудования и т.п., то есть станции не являющиеся производителями, а только продавцами (так сказать, продающих свои ресурсы), Максимальная цена на товар указывается в <price>, наличие товара на станции не менее <amount>, прыжков до станции не больше <jumps>, начиная с сектора <sector>, которая может торговать с кораблем/станцией <trader>. Обратите внимание на следующий момент, при помощи этой инструкции нельзя найти верфь продающую какой либо корабль или станцию, эта инструкция рассчитана на поиск только товаров класс контейнера которых не более XL и апгрейдов.

Возвращает в <RetVar> указатель на станцию если она найдена, null если станции соответствующей условиям поиска нет.

<RetVar/IF> find station sell: resource <product> with min. jumps: max.price=<price>, amount=<amount>, max.jumps=<jumps>, startsector=<sector>, trader=<trader>

Найти станцию продающею товар <product>, с минимальным количеством прыжков до неё. Инструкция будет искать торговые станции или доки оборудования и т.п., то есть станции не являющиеся производителями, а только продавцами (так сказать, продающих свои ресурсы), Максимальная цена на товар указывается в <price>, наличие товара на станции не менее <amount>, прыжков до станции не больше <jumps>, начиная с сектора <sector>, которая может торговать с кораблем/станцией <trader>. Обратите внимание на следующий момент, при помощи этой инструкции нельзя найти верфь продающую какой либо корабль или станцию, эта инструкция рассчитана на поиск только товаров класс контейнера которых не более XL и апгрейдов.

Возвращает в <RetVar> указатель на станцию если она найдена, null если станции соответствующей условиям поиска нет.

<RetVar>=get average price of ware <ware>

Возвращает среднею цену на товар <ware>.

<RetVar>=get max price of ware <ware>

Получить максимальную цену на товар <ware>.

<RetVar>=get min price of ware <ware>

Получить минимальную цену на товар <ware>.

<RetVar>=get max price of ware <ware> as secondary resource

<RetVar>=get min price of ware <ware> as secondary resource

Если указанный товар является вторичным ресурсом, то на него устанавливаются другие максимальные и минимальные цены. Эти две инструкции возвращают соответственно максимальную и минимальную цену на товар являющийся вторичным ресурсом.

<RetVar/IF> is ware <ware> illegal in <race> sectors

Проверить, является ли товар <ware> запрещенным в секторах расы <race>. Возвращает [TRUE] если товар нелегален, [FALSE] если легален.

<RetVar>=get maintype of ware <ware>

<RetVar>=get subtype of ware <ware>

Все товары в игре разделены на типы и подтипы. Первая инструкция возвращает тип, а вторая подтип товара <ware>. Тип – это группа в которую объединены товары по какому либо принципы. Подтип – это идентификационный номер товара внутри группы (maintype). Типы товаров описываются во внутренних файлах описателях находящихся в папке \types, эти файлы содержат информацию о визуальной модели, цене и еще множество внутренних параметров. Подробно тип и принадлежащие им подтипы описаны в приложении «Описание типов и подтипов товаров и объектов»

<RetVar>=get ware from maintype <maintype> and subtype <subtype>

Получить в переменную <RetVar> товар по его типу <maintype> и подтипу <subtype>.

<RetVar>=get number of subtypes of maintype <maintype>

Получить количество подтипов содержащихся в типе <maintype>.

<RetVar/IF>=<object> get maintype

<RetVar/IF>=<object> get subtype

Все объекты в игровой галактике также делятся на типы и подтипы. Эти инструкции возвращают тип и подтип для <object>. Подробно тип и принадлежащие им подтипы описаны в приложении «Описание типов и подтипов товаров и объектов»

<RetVar/IF><object> find
station: product <product> with best price:
max.price=<price>, amount=<amount>,
max.jumps=<jumps>, startsector=<sector>,
trader=<trader>

… find station: product <product> with min. jumps…

… find station: resource <product> with best price: …

… find station: resource <product> with min. jumps: …

… find station sell: resource <product> with best price: …

… find station sell: resource <product> with min. jumps: …

Эти шесть инструкций идентичны описанным выше инструкциям поиска, с той разницей, что максимальное количество прыжков будет считаться от объекта <object>. А в предыдущих инструкциях отсчет ведется от текущей позиции <trader>.

· Для кораблей (Ships)

<RetVar/IF> <ship> buy <count> units of <ware>

Команда кораблю купить товар <ware>, в количестве <count>, на станции к которой корабль пристыкован (это обязательное условие, иначе вернет null). Если в грузовом трюме корабля не хватает места или на станции нет достаточного количества указанного товара, то будет приобретено максимально возможное количество товара (либо сколько войдет, либо сколько есть на станции). Деньги снимаются со счета станции к которой приписан корабль, если корабль не имеет базы приписки, то деньги будут взяты со счета игрока (если не хватает денег то будет приобретено столько товара, на сколько денег хватит). Эта команда не будут работать с кораблями класса «большой корабль» пристыкованного с наружи станции или дока.

Возвращает инструкция количество реально приобретенного товара или null если корабль не пристыкован к станции.

<RetVar/IF> <ship> buy <count> units of <ware> to a max. price of <price> Cr

Команда кораблю купить товар <ware>, в количестве <count>, на станции к которой корабль пристыкован (это обязательное условие, иначе вернет null), если цена товара не выше указанной <price>. Если в грузовом трюме корабля не хватает места или на станции нет достаточного количества указанного товара, то будет приобретено максимально возможное количество товара (либо сколько войдет, либо сколько есть на станции). Деньги снимаются со счета станции к которой приписан корабль, если корабль не имеет базы приписки, то деньги будут взяты со счета игрока (если не хватает денег то будет приобретено столько товара, на сколько денег хватит). Эта команда не будут работать с кораблями класса «большой корабль» пристыкованного с наружи станции или дока.

Возвращает инструкция количество реально приобретенного товара или null если корабль не пристыкован к станции.

<RetVar/IF> <ship> sell <count> units of <ware>

Команда кораблю продать товар <ware>, в количестве <count>, станции к которой корабль пристыкован (это обязательное условие, иначе вернет null). Если в грузовом трюме корабля нет достаточного количества указанного товара, то будет продано максимально возможное количество товара (сколько есть в трюме). Деньги переводятся на счет станции к которой приписан корабль, если корабль не имеет базы приписки, то деньги будут переведены на счет игрока. Эта команда не будут работать с кораблями класса «большой корабль» пристыкованного с наружи станции или дока. Так же, эта команда не будет работать с доком, если в списке продаваемых товаров нет этого товара, хотя команда can bay ware возвращает значение говорящие о том что док покупает этот товар и игрок в ручную может продать этот товар.

Возвращает инструкция количество реально проданного товара или null если корабль не пристыкован к станции.

<RetVar/IF> <ship> load <count> units of <ware>

<RetVar/IF> <ship> unload <count> units of <ware>

Приказ загрузить или выгрузить товар <ware>, в количестве <count> на/со станции к которой корабль пристыкован (это обязательное условие, иначе вернет null). Производиться простая перегрузка товара без перевода денег. В случаях нехватки или излишков товара, действует по принципу предыдущих инструкций (либо загружает, либо выгружает максимальное количество товара). Возвращает количество фактически загруженного или выгруженного товара. Эти команды не будут работать с кораблями класса «большой корабль» пристыкованного с наружи станции или дока. Команда unload не будет работать с доком, если в списке продаваемых товаров нет этого товара, хотя команда can bay ware возвращает значение говорящие о том что док покупает этот товар.

<RetVar>=<ship> get max. ware transport class

Выдает максимальный класс контейнеров (S, M, L, XL), которые может перевозить корабль <ship>.

<RetVar/IF> <ship> get cargo bay size

Возвращает суммарный размер грузового отсека корабля <ship>.

<RetVar/IF> <ship> get free volume of cargo bay

Возвращает количество свободного места в грузовом отсеке корабля <ship>.

<RetVar/IF> <ship> get volume of ware <ware> in cargo bay

Возвращает суммарное количество места занимаемого товаром <ware> в грузовом отсеке корабля <ship>. Обратите внимание на то, что возвращаемое значение это не количество товара, а именно занимаемый им объем места в грузовом отсеке.

<RetVar/IF> <ship> get true volume of ware <ware> in cargo bay

Возвращает объем места занимаемого товаром <ware> в грузовом трюме корабля, если этот товар не является установленным оружием или щитом. Эта инструкция удобна для определения занимаемого места не используемыми щитами и пушками.

<RetVar/IF> <ship> get free volume of ware <ware> in cargo bay

Возвращает, какое количество товара <ware>, можно погрузить в трюм на данный момент (имеется в виду, количество места в грузовом трюме для погрузки данного вида товара).

<RetVar/IF> <ship> get total volume in cargo bay

Возвращает общий занятый объем в грузовом трюме, включая установленное оборудование и все товары.

<RetVar/IF> <ship> can transport ware <ware>

Возвращает, может ли везти корабль <ship> товар <ware>. [TRUE] если может, [FALSE] если нет. Имеется в виду, соответствие классов контейнеров.

<ship> add default items to ship

Добавляет оборудование (пушки, щиты, апгрейды) на корабль <ship>, заданное для данного типа кораблей по умолчанию (стандартная комплектация), и одновременно устанавливает все добавленное оборудование. Эта команда удобна в комплексе с командой create ship. Пушки и щиты ставятся обычно по максимуму, а апгрейды случайным образом. Обратите внимание на то что данная команда не рассчитана на вооружение хаакских кластеров, то есть апгрейды и щиты она добавит, а вот оружие она поставит стандартное для кораблей других рас данного класса, то есть, добавлены будут не совместимые с хаакскими кораблями кионные эмиттеры, а стандартные AIRE и т.п.

<ship> switch laser in turret <turretid> to <gunid> to <gun>

Установить на турель <turretid>, на место пушки <gunid>, пушку <gun>. Если выбрать турель 0, то изменения будут относиться к носовым орудиям, в <gunid> соответственно 0 левая пушка, 1 правая. Устанавливаемые пушки должны иметься в грузовом отсеке и быть совместимыми с турелью (имеется в виду техническая возможность установки). В противном случае изменения не будут произведены.

<ship> set wanted ware count to <count>

Эта инструкция относится к семейству информативных команд и задает значение которое будет отражаться в информационных экранах корабля в графе количество требуемого товара. Эта инструкция предназначена для работы с командами COMMAND_GET_WARE, COMMAND_SELL_WARE или COMMAND_GET_WARE_BEST, COMMAND_SELL_WARE_BEST требуется их предварительная установка (т.е. перед данной инструкции в скрипте должно присутствовать строка например : set command: COMMAND_GET_WARE ). Значение отражается не сразу, а только после того как на борт корабля загружается заданное количество товара предназначенное для продажи или после его покупки, в зависимости от использованной команды.

<ship> set wanted ware to <count>

Эта инструкция относится к семейству информативных команд и задает значение которое будет отражаться в информационных экранах корабля в графе требуемый товар. Эта инструкция предназначена для работы с командами COMMAND_GET_WARE, COMMAND_SELL_WARE или COMMAND_GET_WARE_BEST, COMMAND_SELL_WARE_BEST требуется их предварительная установка (т.е. перед данной инструкции в скрипте должно присутствовать строка например : set command: COMMAND_GET_WARE ).

<RetVar>=<ship> get wanted ware count

Возвращает количество информативное количество необходимого товара для объекта <ship> заданное инструкцией set wanted ware count.

<RetVar>=<ship> get wanted ware

Возвращает необходимый товар для объекта <ship> заданный инструкцией set wanted ware.

<RetVar/IF> <ship> has illegal ware onboard: race=<race>

Возвращает значение [TRUE] если на борту корабля <ship> имеется товар являющийся нелегальным для расы <race> и [FALSE] если нелегального товара нет.

· Для станций (Stations)

<RetVar/IF> <station> get best store amount of ware <ware>

Возвращает 50% от максимального количества продукта или ресурса который может находиться на станции.

<RetVar/IF> <station> get max. store amount of ware <ware>

Возвращает максимальное количество продукта/ресурса <ware>, которое может находиться на станции.

<RetVar/IF> <station> can buy ware <ware>

<RetVar/IF> <station> can sell ware <ware>

Возвращает [TRUE] если станция может покупать/продавать, [FALSE] если нет.

<RetVar/IF> <station> get price of ware <ware>

Возвращает текущую цену на товар <ware> для станции <station>.

<RetVar/IF> <station> get average price of ware <ware>

Возвращает среднюю цену товара <ware> установленную в игре.

<station> set price of ware <ware> to <price> Cr

Установить продажную цену <price> на товар <ware> для станции <station>. Эта инструкция работает только со станциями игрока и позволяет изменять цену в пределах фиксированного диапазона цен (мин.цена – макс.цена).

<RetVar/IF> <station> uses ware <ware> as primary resource

Возвращает [TRUE] если товар <ware> является первичным ресурсом для станции <station>.

<RetVar/IF> <station> uses ware <ware> as secondary resource

Возвращает [TRUE] если товар <ware> является вторичным ресурсом для станции <station>.

<RetVar/IF> <station> trades with ware <ware>

Возвращает [TRUE] если станция торгует товаром <ware> и соответственно [FALSE] если нет.

Эта команда некорректно работает при попытке определить торгует ли верфь определенным кораблем, результат возвращенный инструкцией независимо от того торгует верфь этим кораблем или нет будет [TRUE]. При проверке торгует ли верфь какой либо станцией возвращаемый результат будет корректен.

<RetVar/IF> <station> get product ware

Возвращает товар являющийся продукцией производимой станцией <station> или null если станция не производит продукции (торговые станции, доки, верфи).

<RetVar/IF> <station> get number of resources

Возвращает суммарное количество товарных позиций необходимых ресурсов для станции <station> (первичные+вторичные ресурсы). То есть не требуемое количество ресурса, а количество товарных позиций. Например для аргонского ранчо принадлежащего игроку эта инструкция вернет 1 (батарейки), а принадлежащего любой NPC расе значение 3 (батарейки, планктон, фрукты скруффин).

<RetVar/IF> <station> get number of primary resources

Возвращает количество товарных позиций необходимых первичных ресурсов для станции <station>.

<RetVar/IF> <station> get number of secondary resources

Возвращает количество товарных позиций необходимых вторичных ресурсов для станции <station>.

<RetVar/IF> <station> get max trade jumps

Возвращает максимальное количество прыжков для поиска/продажи товара установленного для транспортных кораблей станции <station>, в меню настройки станции.

<RetVar/IF> <station>only player own ship can trade with

Инструкция возвращает [TRUE] если, только корабли принадлежащие игроку могут торговать со станцией и [FALSE] если станция может торговать со всеми расами.

<RetVar>= <station> get tradeable ware array from station

Возвращает массив связанных со станцией <station> товаров. Возвращаются как ресурсы, так и продукция. Элементы массива не упорядочиваются, то есть все товары идут единым списком без разделения на продукцию, первичные или вторичные ресурсы. Для выделения из массива какой либо группы ресурсов, придется проверять каждый элемент массива на принадлежность к группе при помощи инструкций uses ware as secondary resource или uses ware as primary resource.

Для кораблей и станций (Ships and Stations)

<RetVar/IF> <object> get money

Возвращает количество денег на счете объекта <object>, объектом могу являться станции или принадлежащие им корабли.

<object> add money: <amount>

Добавляет сумму денег <amount> на счет <object>. Объектом могу являться станции или принадлежащие им корабли. Если указать в <amount> отрицательное число то деньги будут списаны со счета объекта.

<RetVar/IF> <object> get amount of ware <ware> in cargo bay

Возвращает фактическое количество товара (не объем, а количество единиц) <ware>, находящегося в грузовом трюме объекта <object>.

<RetVar/IF> <object> get true amount of ware <ware> in cargo bay

Возвращает количество товара (не объем, а количество единиц) находящегося в трюме объекта, за исключением установленного оборудования (щиты, пушки).

<RetVar/IF> <object> get free amount of ware <ware> in cargo bay

Возвращает количество свободного места под погрузку товара <ware> в грузовом отсеке объекта.

<RetVar/IF> <object> get max amount of ware <ware> that can be stored in cargo bay

Возвращает максимально возможное количество товара <ware>, которое можно погрузить в трюм <object>, при условии, что из трюма будет выброшено все остальное, включая пушки и щиты.


Работа с галактикой и секторами

v Команды работы с галактикой и секторами ( Universe and sector commands ).

<RetVar/IF> get sector from universe index: x=<x> y=<y>

Возвращает сектор находящийся по указанным координатам в галактике. В универсальных скриптах не должно быть зависимости от конкретных секторов, это позволит использовать скрипт не только на встроенной в игру карте.

<RetVar>=get max sectors in x direction

Возвращает число 20, что соответствует размеру матрицы карты галактики по оси X. Т.е это максимально возможное количество секторов по оси Х.

<RetVar>=get max sectors in y direction

Возвращает число 15, что соответствует размеру матрицы карты галактики по оси Y. Т.е это максимально возможное количество секторов по оси Y.

<RetVar/IF> <sector> is sector known by the player

Возвращает [TRUE] если игрок посещал сектор <sector>, и [FALSE] если нет.

<RetVar>=<sector> get universe x index

<RetVar>=<sector> get universe y index

Возвращает координату X и Y сектора <sector>.

<RetVar/IF> <sector> get warp gate: gate id <gate>

Находит и возвращает врата с ID <gate>, в секторе <sector>. Под ID подразумевается не ID объекта, а расположение врат относительно сторон света.

ID | Описание
0 | Северные
1 | Южные
2 | Восточные
3 | Западные

Если таких врат не существует, возвращает null. Может использоваться например, для определения какие врата имеются в секторе.

<RetVar>=<sector> get north warp gate

<RetVar>=<sector> get south warp gate

<RetVar>=<sector> get east warp gate

<RetVar>=<sector> get west warp gate

Возвращает соответствующие (северные, южные, западные, восточные) врата из сектора <sector> или null если таких ворот нет.

<RetVar>=find a random sector: startsector=<sector>, jumps=<maxjumps>, owner=<owner>

Найти случайный сектор, принадлежащий расе <owner> начать поиск с сектора <sector>, на удалении не более прыжков <maxjumps>. Параметр расы может быть null, а вот startsector обязательно должен быть указан.

<RetVar>= <object> -> get ship array from sector/ship/station

Возвращает массив содержащий все корабли находящиеся в <object>. Объектом могут являться сектора, корабли, станции.

<RetVar>= <sector> get station array from sector

<RetVar>= <sector> get factory array from sector

<RetVar>= <sector> get dock array from sector

Возвращает массив содержащий все станции/фабрики/доки в выбранном секторе <sector>.

<RetVar>= <sector> get player owned ship array from sector

<RetVar>= <sector> get player owned station array from sector

Возвращает массив кораблей/станций принадлежащих игроку находящихся в секторе <sector>.

<RetVar>= <sector> get asteroid array from sector

Возвращает все астероиды находящиеся в секторе <sector>.


Предисловие к разделу "Статьи пилотов"

Об этом разделе.

В данном разделе будут собраны статьи разных авторов. Все права принадлежат авторам. Тексты приведены в оригинале, за исключением небольших орфографических и оформительских исправлений.

Некоторые статьи написаны первопроходцами скриптописания, и могут содержать неточности. Я не берусь редактировать чужие статьи, мной они только отформатированы для улучшения читаемости.

Этот учебный материал уникален. И по мере наполнения данного раздела, я надеюсь, охватит все аспекты скриптописания.

Концепция скрипта Station Manager (автор aka ANS)

Скрипт захвата астероидов "xt.dp.asteroidcollector" (автор: Антон Поляков aka XenonTomb)

"Учимся писать скрипты" разбираем скрипт Корабль-Склад (автор: Антон Поляков aka XenonTomb)


Захват Астеройда (разбор скрипта)

Статья приведена в оригинальном тексте автора

xt.dp.asteroidcollector (захват астероида)

Это скрипт захвата астероида xt.dp.asteroidcollector из пакета "XenonTomb Device Pack v2". Скрипт задействует самые разные команды: торговые, навигационые, общесистемные, аудио, бортжурнала и проч., использует операторы условного и безусловного перехода, циклы, языковые ресурсы, команды поиска и поэтому, как мне кажется, будет достаточно полезным для обучения. Сам скрипт можно скачать на страничке "Собрание скриптов пилотов". Номера фраз борткомпьютера можно поглядеть в MSCI Handbook на стр. 98.

001 $ship = [THIS]

Передаем переменной $ship указатель на корабль, на котором запущен этот скрипт.

002
003 skip if $ship == [PLAYERSHIP]
004 return null

Проверяем, является ли корабль тем кораблем, в котором сидит игрок, если нет, то выходим из скрипта.

005
006 $loaded = $ship -> get amount of ware Астероид in cargo bay

Получаем в переменную $loaded количество товара "Астероид", предположительно имеющегося на борту.

007 skip if not $loaded
008 goto label unload.asteroid

Проверяем, если товар есть ($loaded>0, что соответствует логическому значению TRUE. Значение 0 считается FALSE), то переходим на метку unload.asteroid (строка 088), чтобы выполнить разгрузку. Если же товара нет, будем загружаться (скрипт выполняется дальше).

009
010 * ---------------------- LOADING --------------------- Это просто коментарий "ЗАГРУЗКА"
011
012 if not $ship -> get free amount of ware Астероид in cargo bay
013 @ = wait 2000 ms
014 = speak text: page=13 id=135 priority=0
015 = speak text: page=13 id=1253 priority=0
016 return null
017 end

Смысл этого блока сводится к следующему: в строке 012 проверяем, сколько товара "Астероид" может поместится в трюм на текущий момент. Можно было бы поступить по-другому: зная, что товар "Астероид" и меет размер 10000 ST, можно узнатькол-во свободного места, поделить его на 10000 и получить кол-во. Команда get free amount of ware позволяет нам не заниматься арифметикой, ничего не знать о возможности корабля перевозить груз ST, и даже не знать, какой размер имеет единица товара, а сразу получить кол-во. Далее, если места для товара нет (команда get free amount of ware вернула 0), то в строке 013 ждем 2 секунды (в это время борткомпьютер договаривает фразу "Автопилот активирован"), в строках 014 и 015 заставляем тетку сказать "Команда отклонена" и "Нехватает места в трюме", и в строке 016 выходим из скрипта. Если же место в трюме у нас есть (команда get free amount of ware вернула число >0), то продолжаем выполнять скрипт.

018
019 $target = get player tracking aim
020 skip if $target -> is of class Астероид
021 goto label not.correct

Получаем в переменную $target указатель на объект, который находится в прицеле к орабля. Далее проверяем, принадлежит ли этот объект классу "Астероид". Если объект - не астероид, переходим по метке not.correct (строка 118), иначе продолжаем выполнять скрипт.

022
023 $dist = get distance between $ship and $target
024 skip if $dist <= 3000
025 goto label not.correct

Получаем в переменную $dist расстояние в метрах между кораблем $ship и целью $target (астероид). Если расстояние более 3000 метров, переходим по метке not.correct, иначе продолжаем выполнять скрипт.

Теперь начинется интересное: выяснение жирности (значения yield) астероида. Задача усложняется тем, что нет функции, которая бы вернула это значение, поэтому придется извращаться. Извращаться мы будем в строках 027-049, используя цикл while.

026
027 $yield = 100
028 while $yield > 0
029 * ore
030 $aster = find asteroid: sector=[SECTOR] resourcetype=0 min.yield=$yield flags=[Find.Nearest] refobj=$ship maxdist=3000 maxnum=null refpos=null
031 if $aster
032 $res.type = 0
033 break
034 end
035 * silicon
036 $aster = find asteroid: sector=[SECTOR] resourcetype=1 min.yield=$yield flags=[Find.Nearest] refobj=$ship maxdist=3000 maxnum=null refpos=null
037 if $aster
038 $res.type = 1
039 break
040 end
041 * nividium
042 $aster = find asteroid: sector=[SECTOR] resourcetype=2 min.yield=$yield flags=[Find.Nearest] refobj=$ship maxdist=3000 maxnum=null refpos=null
043 if $aster
044 $res.type = 2
045 break
046 end
047 dec $yield =
048 @ = wait 5 ms
049 end

Разберем подробно. В строке 027 присвоим переменной $yield значение 100 - это наша точка отсчета, максимальная жирность (для стандартной игры). Это значение можно сделать и побольше, если существуют такие астероиды небольшого размера. Далее организуем цикл (строки 028-049), который будет выполняться, пока значение $yield будет больше 0. В строке 030 мы попытаемся найти ближайший астероид (флаг поиска - Find.Nearest) с типом ресурса "руда", минимальной жирностью $yield (в первом витке цикла равной 100), находящийся на расстоянии не более 3000 м от корабля $ship. Результат поиска функции find asteroid возвращается в переменную $aster. Далее в строках 031-034, если искомый астероид обнаружен (переменная $aster не равна null), то переменой $res.type мы присваиваем значение 0 (тип ресурса - руда), и прерываем цикл командой break. В строках 036-040 и 042-046 мы делаем то же самое, только для ресурсов "кремний" и "нивидиум" (типы ресурсов 1 и 2 соответственно). В строке 047 мы уменьшаем значение $yield на единицу перед следующим витком цикла. Строка 048 - простая задержка, чтоб интенсивные вычисления в цикле не затормаживали игру. Подитожим: цикл выполняется либо до того, как $yield достигнет значения 0 (это значит что мы не нашли астероид, что маловероятно), либо цикл прерывается на любом витке при нахождении астероида. Во втором случае переменная $yield сохранит значение жирности астероида - помним об этом!

050
051 skip if $aster == $target
052 goto label not.correct

Проверяем, совпадает ли наш найденый астероид с тем астероидом, который у нас в прицеле. Если нет, то переходим по метке not.correct, иначе продолжаем выполнять скрипт. Значения $aster и $target могут не совпасть лишь в двух случаях: если мы не нашли астероид в цикле ($aster=null), или если в 3000 м от корабля были два астероида с одинаковой жирностью, причем нецелевой астероид оказался немного ближе к кораблю, чем целевой, что также маловероятно.

053
054 $energy = $ship -> get amount of ware Кристаллы in cargo bay
055 skip if $energy >= 25
056 goto label not.correct

Получаем в переменную $energy количество кристаллов, находящихся в трюме корабля. Если их меньше 25, то переходим по метке not.correct, иначе движемся дальше.

057
058 $aster.type = $aster -> get subtype

Получаем в переменную $aster.type подтип нашего астроида, отвечающий за его внешний вид.

059 $aster.param = array alloc: size=3
060 $aster.param[0] = $res.type
061 $aster.param[1] = $yield
062 $aster.param[2] = $aster.type

Распределяем в памяти массив $aster.param из трех ячеек, которым присваиваем значения ресурса, жирности и подтипа астероида.

063 $ship -> set local variable: name='asteroid' value=$aster.param

Объявляем для корабля $ship локальную переменную 'asteroid' и присваиваем ей значение массива $aster.param.

064
065 $ID = $aster -> get SectorObject ID
066 free sector object $ID

Получаем в переменную $ID уникальный номер астероида в секторе, и уничтожаем его. При уничтожении он просто пропадает.

067
068 = $ship -> add 1 units of Астероид
069 = $ship -> add -25 units of Кристаллы

Добавляем в трюм корабля 1 единицу товара "Астероид", и убираем из трюма 25 кристаллов.

070
071 = speak text: page=13 id=1257 priority=0
072 = speak text: page=17 id=3721 priority=0

Заставляем борткомпьютер сказать "Теперь трюм содержит..." "Астероид".

073
074 $owner = [SECTOR] -> get owner race

Получаем в переменную $owner расу-владельца сектора, в котором находимся.

075 if $owner == Аргон OR $owner == Борон OR $owner == Сплит OR $owner == Паранид OR $owner == Телади
076 @ = wait 500 ms
077 $sum = $yield * -1000
078 add money to player: $sum
079 $sum = - $sum
080 player loses police licence for race $owner
081 write to player logbook: printf: pageid=511 textid=20, $owner, $sum, null, null, null
082 = speak text: page=13 id=20 priority=0
083 end

Если раса-владелец одна их перечисленных в строке 075, то ждем полсекунды; в строке 077 вычисляем сумму штрафа (жирность*-1000); в строке 078 снимаем эту сумму со счета игрока (команда add money добавляет отрицательное число); в строке 079 меняем знак у суммы штрафа; в строке 080 лишаем игрока лицензии расы $owner; в строке 081 записываем в бортжурнал игрока матюков от расы-владельца, подставляя в текст расу и сумму штрафа; в строке 082 тетка говорит, что "Получено сообщение". Текст матюков берется из языкового файла пакета, который подгружается при инициализации скрипта (здесь мы это не рассматриваем).

084
085 return null

Все, погрузка завершена, выход из скрипта.

086
087 * ---------------------- UNLOADING --------------------- Коментарий "РАЗГРУЗКА"
088 unload.asteroid:

Это наша метка "разгрузка", на которую мы переходим из начала скрипта, когда обнаруживаем наличие астероида на борту.

089
090 $energy = $ship -> get amount of ware Кристаллы in cargo bay
091 skip if $energy >= 25
092 goto label not.correct

Проверяем, есть ли у нас 25 кристаллов для операции разгрузки. Если их меньше, то переходим по метке not.correct, иначе движемся дальше.

093
094 $aster.param = $ship -> get local variable: name='asteroid'

Читаем значение локальной переменной 'asteroid', и предаем его в массив $aster.param.

095 $res.type = $aster.param[0]
096 $yield = $aster.param[1]
097 $aster.type = $aster.param[2]

Присваиваем значения ячеек массива переменным ресурса, жирности и подтипа астероида. Мы с ними уже знакомы.

098
099 $x = $ship -> get x position
100 $y = $ship -> get y position
101 $z = $ship -> get z position

Получаем в соответствующие переменные значения координат корабля в секторе.

102 $x = $x + 2000
103 $y = $y + 2000
104 $z = $z + 2000

Увеличиваем значения координат на 2000 м каждую.

105 $aster = create asteroid: type=$aster.type addto=[SECTOR] resource=$res.type yield=$yield x=$x y=$y z=$z

Создаем астероид в текущем секторе с необходимыми параметрами, с координатами х,у и z, и передаем указатель на астероид пременной $aster.

106 skip if $aster
107 return null

На всякий случай проверяем, создался ли астероид. Если нет ($aster=null), то выходим из скрипта. Это может произойти в случае, если мы не захватывали астероид как положено, а тупо добавили его в трюм командой add ware. Соответственно, у нас не будет нужных параметров астероида, хранящихся в локальной переменной 'asteroid'. Но ведь мы не читеры, так делать не будем!

108
109 = $ship -> add -1 units of Астероид
110 = $ship -> add -25 units of Кристаллы

Удаляем из трюма астероид и 25 кристалов.

111
112 @ = wait 2000 ms
113 = speak text: page=17 id=3721 priority=0
114 = speak text: page=13 id=5 priority=0

Борткомпьютер говорит: "Астероид" "выброшен".

115
116 return null

Все, выход из разгрузки.

117
118 not.correct:
119 @ = wait 2000 ms
120 = speak text: page=13 id=135 priority=0
121 return null

А вот и махонькая подпрограмма, в которыю мы переходим при ошибках. Здесь автопилот говорит "Команда отклонена" и происходит выход из скрипта.


Концепция "Station Manager"

Статья приведена в оригинальном тексте автора

Station Manager

Все, кто развивал промышленность (до выхода версии 1.4) сталкивались с необходимостью сбрасывать излишки денег со счетов станций на свой счет (и наоборот - подпитывать станции на этапе раскрутки и активной закупки сырья).

Когда станций больше десяти (а со временем счет может дойти до сотни) это уже напрягает. Существует масса готовых скриптов, но я здесь подробно расскажу о своем скрипте - просто чтобы на этом примере могли научиться новички.

Скрипт называется station manager (как-бы нанятый управляющий). Был написан изначально для версии 1.2, но с выходом 1.4 слегка переработан (команды перенесены в консоль станций и кое-что еще по-мелочи).

Техзадание

1. Станция имеет нижнее и верхнее ограничение остатка на счете. Если денег на счете больше - излишек переводится на основной счет игрока. Если денег меньше - счет станции пополняется со счета игрока до нижнего предела. У каждой станции эти пределы выставляются индивидуально.

2. Основной счет игрока имеет нижнее ограничение. Деньги из этого резерва не могут быть использованы для пополнения счета станции (чтобы не пропадали нанятые TL).

3. Игрок сам выбирает - какие станции будут иметь управляющего. В любой момент любая станция может выключена в список управляемых, может быть исключена из этого списка.

4. В любой момент должна быть доступна статистика - список управляемых станций, количество денег, переведенных со станции (или на станцию). Нужно для выявления неэффективных (или недостаточно эффективных) станций.

Выбор способа

Очевидно, задача решается двумя основными способами.

Первый - на каждой станции свой скрипт, управляющий данной конкретной станцией. Так сделан стандартный скрипт в версии 1.4.

Поскольку до выхода этой версии к станции мог быть привязан только один скрипт (а не десять как сейчас), я выбрал тогда (для 1.2) другой способ - один глобальный скрипт, управляющий сразу всеми станциями).

Оба способа по большому счету равноправны.

Общий алгоритм действий

Основной скрипт, разбитый для удобства на три части

1. Инициализация (init.StationManager.controls)

В момент старта скрипта проверяется наличие ряда глобальных переменных. Если таковых нет - скрипт создает и регистрирует эти переменные. Помимо этого, скрипт выставляет в командное меню абсолютно всех кораблей игрока несколько команд (нанять менеджера для станции, уволить менеджера со станции, дать отчет по движению денег, установить неснижаемый остаток основного счета).

2. Основной цикл (StM.mainloop)

a. Для каждой станции в списке управляемых станций исполнить скрипт StM.justifymoney с параметрами Station (объект:станция), min (число:нижний предел остатка на счете станции), max (число:верхний предел остатка на счете станции), cfund (число:неснижаемый остаток на основном счете игрока).

b. Число, возвращенное скриптом, запомнить как сумму денег, переведенную на счет игрока (это число может быть и отрицательным).

c. Подождать определенный промежуток времени.

d. Повторить.

3. Управление счетом станции (StM.justifymoney)

Аргументы:

Station - объект:станция;

min - число:нижний предел остатка на счете станции;

max - число:верхний предел остатка на счете станции;

cfund - число:неснижаемый остаток на основном счете игрока.

Результат:

fee - число:сумма денег, переведенная на счет игрока.

a. Получить в переменную player сумму денег на счете игрока (с учетом неснижаемого остатка).

b. Получить в переменную account сумму денег на счете станции.

с. Вычислить и поместить в переменную need сумму денег, которую необходимо перевести на счет игрока (число может быть отрицательным).

d. Выислить (player + need), (account - need).

e. Установить счет игрока равным player, счет станции равным account.

f. Вернуть в вызывающий скрипт значение need.

Для чего основной алгоритм разбит на части и разбросан по разным скриптам ? Инициализация и основной цикл разделены по соображениям удобства написания и редактирования. Алгоритм регулирования счета отдельной станции вынесен в собственный скрипт из соображений удобства модификации и повторного использования кода. Встроенный язык скриптов не имеет механизма описания функций - аналогом функции является сам скрипт. В него можно передавать параметры, он может возвращать результат.

Команды игрока и их обработка

1. Найм менеджера на станцию (StM.install)

Аргументы:

Station - объект:станция;

min - число:нижний предел остатка на счете станции;

max - число:верхний предел остатка на счете станции.

a. Проверить наличие станции Station в списке управляемых станций.

b. Если станция уже в списке - установить новые значения для верхнего и нижнего пределов ее счета равными соответственно параметрам max и min, завершить скрипт.

c. Если станции в списке нет - найти в списке станцию, расположенную в том же секторе, что и Station.

d. Если такая станция найдена - включить Station в список прямо перед найденной станцией.

e. Если такая станция не найдена - добавить Station в конец cписка станций.

f. Обнулить счетчики переведенных со станции денег, установить пределы счета станции, увеличить счетчик станций в списке.

g. Поместить в logbook сообщение о найме менеджера.

Для чего такие сложности с поиском станций из того же сектора? Это нужно для того, чтобы станции из одного сектора шли в списке подряд. Тогда мы и в итоговом отчете очень легко сгруппируем станции по секторам. А группировать станции по секторам нужно для того, чтобы их названия помещались в одну строку на экране, тогда список станций в отчете будет смотреться как стройная, легко читаемая таблица. Да и легче в таком списке найти нужную строку - сначала находим сектор, затем - станцию в секторе.

2. Найм менеджеров сразу на все станции игрока (StM.install.all)

Аргументы:

min - число: нижний предел остатка на счете каждой станции;

max - число: верхний предел остатка на счете каждой станции.

a. Для каждого сектора галактики получить список станций игрока, размещенных в этом секторе.

b. Для каждой станции в списке исполнить скрипт StM.install.

3. Увольнение менеждера со станции (StM.remove)

Аргументы:

Station - объект: станция.

a. Если станция присутствует в списке станций, управляемых скрптом - исключить ее из списка и записать соответствующее сообщение в logbook.

4. Отчет о движении денег (StM.report.all)

a. Показать название сектора для первой станции в списке.

b. Для каждой станции из списка сформировать строку, содержащую:

- название станции;

- общую сумму денег, переведенную со счета станции на счет игрока за все то время, что счетом управляет нанятый менеджер;

- сумму денег, переведенную со счета станции на счет игрока за время, прошедшее с момента выдачи предыдущего отчета.

c. Если следующая станция в списке размещена в другом секторе, показать название этого сектора.

d. Сформировать заголовок отчета, содержащий текущую дату, дату выдачи предыдущего отчета, общую сумму денег, переведенных со всех станций за все время, общую сумму денег, переведенных со всех станций с момента выдачи предыдущего отчета.

e. Записать заголовок в logbook игрока, записать полный отчет во внешний log-файл.

5. Установка значния неснижаемого остатка (StM.setcfund)

Аргумент:

cfund - число:неснижаемый остаток на основном счете игрока.

a. Установить значение cfund.

Структуры данных

Для каждой станции нам нужно хранить несколько различных параметров.

Во-первых, нужна ссылка на сам объект-станцию. Иначе мы не сможем управлять ее счетом.

Во-вторых, нужно хранить нижний и верхний пределы счета станции, общую сумму денег, перечисленных со счета станции и сумму денег, перечисленную со времени выдачи последнего отчета.

В более продвинутых языках программирования мы смогли бы создать структуру для каждой станции. В этом языке понятие структуры отсутствует, поэтому мы сделаем по одному массиву для каждого параметра.

Массив ссылок на объекты-станции назовем StMst.

Массивы верхних и нижних пределов счета назовем StMjmMax и StMjmMin соответственно.

Массив общих сумм назовем StMtotal.

Последний массив (суммы, переведенные с момента выдачи последнего отчета) назовем StMdiff.

Общее количество станций в списке будем хранить в переменной StMnum.

Сумму неснижаемого остатка счета игрока будем хранить в переменной StMcfund.

Дату выдачи последнего отчета будем хранить в переменной StMlastrep.

Поскольку ко всем этим данным доступ должны иметь несколько скриптов, все переменные должны быть глобальными. Что это значит?

Приватные, локальные и глобальные переменные.

Привязка скриптов.

При запуске любого скрипта, первое что определяет скриптовый движок - к чему, к какому объекту будет привязан скрипт. Это может быть корабль, станция, астероид - что угодно. Или же скрипт может быть не привязанным ни к одному объекту, такие скрипты являются глобальными.

У каждого скрипта могут быть приватные переменные. Собственно, какие-либо операции (математические, логические, операции сравнения) можно производить только над приватными переменными.

Каждый скрипт имеет доступ только к своим собственным приватным переменным, переменные другого скрипта ему недоступны.

Локальные переменные по сути своей напоминают файлы на жестком диске компьютера: вы можете создать файл, стереть его или перезаписать его содержимое целиком - но для редактирования файла вы должны сначала прочитать его в память компьютера, отредактировать и снова записать на жесткий диск. Точно так же дела обстоят с локальными переменными: чтобы что-то сделать с ними, вы должны сначала прочитать значение локальной переменной и присвоить его приватной переменной. Делается это командой get local variable.

Чтобы прочитать значение локальной переменной вам нужно знать ее имя (точно так же, как в случае с файлом на жестком диске) и, помимо этого, нужно знать, какому объекту эта переменная принадлежит. Чтобы присвоить локальной переменной новое значение, нужно воспользоваться командой set local variable.

Глобальные переменные от локальных отличаются тем, что (как и глобальные скрипты) они не привязаны ни к одному объекту, поэтому доступны всем скриптам просто по имени. Функции доступа к глобальым переменным назыаются get global variable и set global variable.

Теперь понятно, почему мы вынуждены для глобальных переменных выбирать длинные и сложные имена - чтобы уменьшить вероятность совпадения имен глобальных переменных у разных скриптов. С этой целью все глобальные переменные нашего скрипта начинаются с букв "StM" (Station Manager).

Но если от посторонних скриптописателей мы отделались с помощью сложных имен переменных, то с нашими собственными скриптами все обстоит немного сложнее.

Если внимательно посмотреть на алгоритмы наших скриптов, становится заметна такая вещь: легко может возникнуть ситуация, когда основной скрипт будет обрабатывать список станций и переводить деньги, а в этот момент пилот решит добавить в список управляемых новую станцию. Или захочет удалить из списка

существующую.

Что тут может быть неприятного? По логике работы с глобальными переменными, наш основной скрипт сначала прочтет глобальные переменные и присвоит прочитанные значения своим приватным переменным. Затем произведет необходимые операции со своими приватными переменными и в конце-концов запишет значения своих

приватных переменных в глобальные переменные. Само-собой, старые значения глобальных переменных при этом пропадут бесследно. Так что если во время активной работы основного скрипта StM.mainloop мы вызовем скрипт StM.install и с его помощью добавим станцию в список, то в момент завершения активной работы StM.mainloop перепишет значения глобальных переменных и внесенные ранее изменения пропадут - станция добавлена в список не будет.

Тут опять уместна аналогия с файлами в сетевом доступе. Вы открыли файл, редактируете его. В этот момент на другой машине кто-то тоже открыл тот же самый файл и тоже его редактирует. Тот из вас, кто запишет файл первым, потеряет свои изменения - после того, как второй редактирующий запишет свои изменения поверх.

Как этого избежать? Точно так же, как этого избегают в случае доступа к файлам - с помощью блокировок.

Блокировки

Смысл блокировок - дать понять всем, что кто-то сейчас редактирует значения глобальных переменных и еще не записал изменения. Тогда те, кто тоже желает внести измения в значения этих же переменных должны дождаться снятия блокировки.

Мы сделаем это просто. Заведем себе специальную глобальную переменную по имени StMlock. Если эта переменная имеет значение false - это будет означать, что никто в этот момент не редактирует значения глобальных переменных.

Тогда логика работы наших скриптов будет такой:

a. Получить значение StMlock

b. Если StMlock == FALSE, перейти к пункту d.

с. Перейти к пункту a.

d. Переменной StMlock присвоить значение TRUE.

После окончания редактирования значений глобальных переменных присвоить переменной StMlock значение false.

Это очень простая, примитивная блокировка. Но наш скрипт тоже не из сложных, для него такой блокировки будет достаточно.

Поскольку подобная блокировка может понадобиться для других скриптов - есть смысл оформить еще (с некоторыми дополнениями) в специальный служебный скрипт.

Скрипт блокировки ANS.lock

Аргументы

LockName - строка:имя глобальной переменной, используемой для блокировки. В нашем случае - StMlock

Pause - число:длительность паузы между проверками переменной (в миллисекундах). Чтобы дать возможность выполняться другим скриптам, мы обязательно должны делать паузу в подобных циклах проверки. Этот аргумент задает длительность паузы в миллисекундах.

Tries - число:количество проверок. Если мы не можем неопределенно долго ждать снятия блока, у нас есть возможность ограничить число попыток. Если же это число оставить равным нулю - скрипт будет ожидать снятия блокировки до победного.

Результат

Скрипт возвращает FALSE в том случае, когда после заданного числа попыток не удалось дождаться снятия блока.

Значение TRUE в результате исполнения скрипта означает, что вы теперь смело можете редактировать свои глобальные переменные.

Текст скрипта:

// Эти две строчки будут исполнены один раз при старте скрипта

001 $lock = get global variable: name=$LockName

002 $try = $Tries

// Эти строки (003-011) будут исполняться снова и снова - пока не исчерпаются попытки или пока глобальная переменная не примет значение FALSE

003 while $lock == [TRUE]
004 @ = wait $Pause ms
005 $lock = get global variable: name=$LockName
006 if $Tries != 0
007 dec $try =
008 skip if $try != 0
009 return [FALSE]
010 end
011 end

// Как только блокирующая переменная приняла значение FALSE (это означает, что другой скрипт записал измененные значения в наши глобальные переменные), мы тут же блокируем их, устнавливая значение блокируюшей переменной в TRUE.

012 set global variable: name=$LockName value=[TRUE]
013 return [TRUE]

Применение

Скрипт ANS.lock вызывается в самой первой строчке каждого скрипта, меняющего значения глобальных переменных:

001 @ = [THIS] -> call script 'ANS.lock' : LockName='StMlock' Pause=2000 Tries=0

После записи новых значений в глобальные переменные обязательно нужно не забыть сбросить флаг блокировки:

057 set global variable: name='StMlock' value=[FALSE]

Дата и время. (Еще один служебный скрипт).

Поскольку в отчетах мы намерены показывать текущую дату и дату предыдущего отчета - нам понадобится скрипт, превращающий понятное компьютеру игровое время в понятную человеку игровую дату.

Дело в том, что игровое время представляет собой число секунд, прошедших с момента старта сюжета игры. Чтобы превратить его в игровую дату, применяем служебный скрипт ANS.format.date.

Аргумент:

ticks - число: число секунд с момента начала игры.

Текст скрипта:

001 $x = $ticks

// Операция целочисленного деления - секунды превращаются в целые минуты, остаток отбрасывается. Примеры: 59 / 60 = 0, 61 / 60 = 1.

002 $x = $x / 60

// Операция получения остатка от деления - получаем минуты текущего часа

003 $m = $x mod 60

// Наводим красоту - если минут меньше десяти - приписываем к числу минут ведущий нолик. Так 17:2 превращается в 17:02.

004 skip if $m > 9

005 $m = '0' + $m

// Превращаем минуты в часы и продолжаем...

006 $x = $x / 60

007 $h = $x mod 24

008 skip if $h > 9

009 $h = '0' + $h

010 $x = $x / 24 + 1

011 $d = $x mod 30

012 skip if $d > 9

013 $d = '0' + $d

014 $x = $x / 30 + 7

015 $n = $x mod 12

016 skip if $n > 9

017 $n = '0' + $n

018 $x = $x / 12 + 764

// Собираем результат в единое целое - год-месяц-день час:мин

019 $res = sprintf: fmt='%s-%s-%s %s:%s', $x, $n, $d, $h, $m

020 return $res

Применение:

044 $date = playing time

047 @ $date = [THIS] -> call script 'ANS.format.date' : ticks=$date

Автоматический запуск скриптов и назначение собственных команд

При старте игры и при загрузке сэйва автоматически запускаются скрипты с именами, начинающимися на "init." и "!plugin.".

Скрипты типа "!plugin." должны иметь цифровую подпись. Чтобы не морочить себе голову с этим, назовем свой скрипт инициализации "init.StationManager.controls".

Задача скрипта инициализации - включить в командную консоль всех баз игрока свои команды управления счетом. Кроме того, нужно будет запустить глобальный скрипт управления счетами - в том случае, если он не был запущен ранее.

Текст скрипта:

// Первый оператор включает в командную консоль всех станций игрока команду с идентификатором COMMAND_TYPE_STATION_10 и назначает этой команде скрипт для исполнения с именем StM.install.this.

001 global script map: set: key=COMMAND_TYPE_STATION_10, class=Station, race=Player, script='StM.install.this', prio=0

// Второй оператор определяет, какие апгрейды должна иметь станция, чтобы команда COMMAND_TYPE_STATION_10 была доступна в консоли станции. Значение TRUE делает команду доступной всегда.

002 set script command upgrade: command=COMMAND_TYPE_STATION_10 upgrade=[TRUE]

// Эти операторы включают остальные четыре команды

004 global script map: set: key=COMMAND_TYPE_STATION_11, class=Station, race=Player, script='StM.install.all', prio=0

005 set script command upgrade: command=COMMAND_TYPE_STATION_11 upgrade=[TRUE]

006

007 global script map: set: key=COMMAND_TYPE_STATION_12, class=Station, race=Player, script='StM.report.all', prio=0

008 set script command upgrade: command=COMMAND_TYPE_STATION_12 upgrade=[TRUE]

009

010 global script map: set: key=COMMAND_TYPE_STATION_13, class=Station, race=Player, script='StM.setcfund', prio=0

011 set script command upgrade: command=COMMAND_TYPE_STATION_13 upgrade=[TRUE]

012

013 global script map: set: key=COMMAND_TYPE_STATION_19, class=Station, race=Player, script='StM.remove.this', prio=0

014 set script command upgrade: command=COMMAND_TYPE_STATION_19 upgrade=[TRUE]

// Если глобальная переменная StMnum не определена (имеет значение null), делаем вывод о том, что скрипт инициализации запущен в первый раз (самое начало игры либо игрок только что установил наш скрипт себе на машину). В этом случае нужно инициализировать все глобальные переменные и запустить скрипт с основным циклом управления счетами.

016 $StMnum = get global variable: name='StMnum'

017 if $StMnum == null

018 set global variable: name='StMnum' value=0

019 set global variable: name='StMcfund' value=10000

// Этот оператор создает массив, не содержащий элементов - заготовку массива. Добавлять элементы в такой "пустой" массив можно оператором insert <элемент> into array <массив> at index <индекс массива>

021 $StMsts = array alloc: size=0

022 set global variable: name='StMsts' value=$StMsts

023 $StMjmMax = array alloc: size=0

024 set global variable: name='StMjmMax' value=$StMjmMax

025 $StMjmMin = array alloc: size=0

026 set global variable: name='StMjmMin' value=$StMjmMin

027 $StMtotal = array alloc: size=0

028 set global variable: name='StMtotal' value=$StMtotal

029 $StMdiff = array alloc: size=0

030 set global variable: name='StMdiff' value=$StMdiff

031

032 $StMlastrep = playing time

033 set global variable: name='StMlastrep' value=$StMlastrep

// Не забываем установить начальное значение для блокирующей переменной. В принципе, если мы не установим его - ничего страшного не произойдет. Переменная будет поначалу иметь значение null, а блокирующим является значение TRUE. Но лучше завести себе привычку в явном виде инициализировать все переменные. Такая привычка впоследствии сэкономит очень много времени и нервов.

035 set global variable: name='StMlock' value=[FALSE]

// Такая команда запускает отдельный скрипт примерно так же, как вы запускаете ракету - выстрелил-и-забыл. Дальше этот скрипт живет сам по себе, а запущенный командой START - совершенно отдельно от него.

037 @ START [THIS] -> call script 'StM.mainloop' :

038 end

040 return null

После исполнения этого скрипта (а он запускается автоматически при старте новой игры или при загрузке сэйва) мы получим в меню каждой своей станции пять команд вида ReadText2010-1110[ReadText2011-1110]. Работать команды будут так, как им положено - но хотелось бы видеть осмысленный текст в их названии.

Как команду назовете, так она и поплывет

Числа в загадочных словах ReadText2010-1110 имеют определенное значение.

Первое число (2010) - идентификатор текстовой страницы, второе - идентификатор строки.

Что это за страницы и строки?

Все тексты, присутствующие в игре (все экраны интерфейса, сообщения бортового компьютера, миссии BBS, сюжетные тексты) размещены в файпах с именами вида XXnnnn.xml (в распакованной версии). Здесь XX - это идентификатор языка текстов (44 для английского языка, 49 для немецкого, 70 для русского и т.д.). А nnnn - это номер файла. Первый файл имеет номер 0001, второй 0002 и так далее.

Внутри файлы имеют такую структуру:

<?xml version="1.0" encoding="UTF-8" ?>

<language id="идентификатор языка текстов">

<page id="номер страницы" title="название страницы" descr="описание страницы">

<t id="номер строки">строка</t>

</page>

</language>

Таким образом, каждая строка однозначно идентифицируется двумя числами - номером страницы и номером строки в пределах страницы.

Когда игра при старте или загрузке читает файлы текстов, она начинает с первого файла (440001.xml для английской версии), затем читает 440002.xml и так далее. При этом строки из последнего файла дополняют страницы, считанные из файлов с меньшими номерами.

Теперь ясно, что для корректного отображения наших команд нам нужен файл с именем, например, 440003.xml и с таким содержимым:

<?xml version="1.0" encoding="UTF-8" ?>

<language id="44">

<page id="2010" title="Commands" descr=" ">

<t id="1110">Hire manager to this station</t>

<t id="1111">Hire manager to all stations</t>

<t id="1112">Industry profit and loss statement</t>

<t id="1113">Set contigency fund</t>

<t id="1119">Fire manager from this station</t>

</page>

<page id="2011" title="Commands" descr=" ">

<t id="1110">StM</t>

<t id="1111">StM</t>

<t id="1112">StM</t>

<t id="1113">StM</t>

<t id="1119">StM</t>

</page>

</language>

Страница 2010 содержит полные названия команд. Страница 2011 содержит краткие названия тех же самых команд. Сделано это для корабельных скриптов - краткие названия отображаются в кокпите вашего корабля (где нет особо много места под длинные надписи).

В нашем случае команды не будут постоянно исполняться на станциях - этим занимается отдельный скрипт StM.mainloop, а значит краткие названия нам совсем ни к чему. Но и оставить пустые строчки мы не можем - разработчики X2 не особо напрягали себя обработкой различных "нештатных" ситуаций, так что игра просто молча умрет при запуске.

Еще два служебных скрипта. Константа THIS.

Если вы обратили внимание - в командах найма и увольнения менеджера запускаются скрипты StM.install.this и StM.remove.this. Единственное, что делают эти скрипты - запускают StM.install и StM.remove таким образом, чтобы их параметр Station содержал ссылку на станцию, в консоли которой была выбрана соответствующая команда. Вот их текст.

StM.install.this

Аргументы

min - число:нижний предел остатка на счете станции;

max - число:верхний предел остатка на счете станции.

Скрипт :

001 @ = [THIS] -> call script 'StM.install' : Select station=[THIS] Low boundary of station account=$min Top boundary of station account=$max

002 return null

Здесь мы видим подстановку константы THIS вместо параметра Station. Что это за константа?

Системная константа THIS всегда указывает на объект, из командной консоли которого был запущен скрипт. Если запускаем из командной консоли станции, THIS указывает на эту станцию. Если из консоли корабля, в котором находимся - указывает на этот корабль (тогда константы THIS и PLAYERSHIP указывают на один и тот ж объект).

Эту константу точно так же использует скрипт StM.remove.this:

001 @ = [THIS] -> call script 'StM.remove' : Select station to fire manager=[THIS]

002 return null

Сразу разберемся с еще одним простым скриптом - StM.setcfund.

StM.setcfund

Все, что он делает - устанавливает новое значение для неснижаемого остатка на счете игрока. Здесь даже не обязательно использовать блокировку - достаточно просто дать глобальной переменной новое значение.

Аргументы

cfund - число:неснижаемый остаток на основном счете игрока.

Скрипт

001 set global variable: name='StMcfund' value=$cfund

002 return null

Основной цикл управления счетами станций (StM.mainloop)

Скрипт:

// Скрипт представляет собой бесконечный цикл. Пока игрок жив - менеджеры станций должны делать свою работу. Даже если станций пока (или уже) нет.

001 while [TRUE]

// Нет смысла непрерывно сканировать счета - надо дать поработать остальным скриптам. Делаем между сканированием паузу длительностью в одну минуту.

002 @ = wait 60000 ms

// Начало активной фазы - блокируем глобальные переменные

004 @ $lock = [THIS] -> call script 'ANS.lock' : LockName='StMlock' Pause=2000 Tries=0

// Глобальные переменные заблокированы, теперь их никто не поменяет пока мы не закончим активную фазу. Считываем значения глобальных переменных.

006 $StMsts = get global variable: name='StMsts'

007 $StMnum = get global variable: name='StMnum'

008 $StMjmMin = get global variable: name='StMjmMin'

009 $StMjmMax = get global variable: name='StMjmMax'

010 $StMtotal = get global variable: name='StMtotal'

011 $StMdiff = get global variable: name='StMdiff'

012 $StMcfund = get global variable: name='StMcfund'

// Проходим по списку станций.

014 $i = 0

015 while $i < $StMnum

// Получаем очередную станцию из списка. Если станция к этому моменту уже не существует в галактике (враги сожгли родную хату) - удаляем эту станцию из общего списка и уменьшаем общее количество станций.

017 $st = $StMsts[$i]

018 if not $st -> exists

019

020 remove element from array $StMsts at index $i

021 remove element from array $StMdiff at index $i

022 remove element from array $StMjmMax at index $i

023 remove element from array $StMjmMin at index $i

024 remove element from array $StMtotal at index $i

025 dec $StMnum =

026

027 else

// Станция жива - вызываем для нее скрипт StM.justifymoney с параметрами, специфичными именно для этой станции.

029 $min = $StMjmMin[$i]

030 $max = $StMjmMax[$i]

031 $total = $StMtotal[$i]

032 $diff = $StMdiff[$i]

// Скрипт возвращает сумму денег, переведенную со счета игрока на счет станции.

034 @ $fee = [THIS] -> call script 'StM.justifymoney' : Station=$st Min=$min Max=$max cfund=$StMcfund

// Учитываем эту сумму в общей сумме платежей и в сумме платежей со времени последнего отчета.

036 $total = $total - $fee

037 $diff = $diff - $fee

038 $StMtotal[$i] = $total

039 $StMdiff[$i] = $diff

040 end

// Берем следующую станцию в списке.

042 inc $i =

043 end

// Активная фаза завершена - записываем новые значения глобальных переменных.

045 set global variable: name='StMtotal' value=$StMtotal

046 set global variable: name='StMdiff' value=$StMdiff

047 set global variable: name='StMjmMax' value=$StMjmMax

048 set global variable: name='StMjmMin' value=$StMjmMin

049 set global variable: name='StMsts' value=$StMsts

050 set global variable: name='StMnum' value=$StMnum

// Снимаем блокировку с глобальных переменных...

052 set global variable: name='StMlock' value=[FALSE]

// ... и переходим на начало бесконечного цикла - к паузе длительностью 60 сек.

054 end

055 return null

Служебный скрипт StM.justifymoney

Аргументы:

Station - объект:станция;

min - число:нижний предел остатка на счете станции;

max - число:верхний предел остатка на счете станции;

cfund - число:неснижаемый остаток на основном счете игрока.

Результат:

fee - число:сумма денег, переведенная со счета игрока на счет станции.

Текст скрипта:

// Получаем количество денег на счету станции

001 $account = $station -> get money

// Получаем количество денег на счету игрока. Сразу уменьшаем это количество на сумму неснижаемого остатка - чтобы не испытывать соблазна.

002 $player = get player money

003 $player = $player - $cfund

// По умлочанию, если количество денег на счету станции укладывается в заданные границы - переводить деньги не требуется

004 $need = 0

// Если сумма денег на счету станции ниже минимума

005 if $account < $min

// Если при этом остаток свободных денег на счету игрока меньше, чем необходимо для пополнения счета станции - переводим на счет станции все, что остается у игрока (за вычетом неснижаемгого остатка - для этого его и водили).

006 if $player < $min - $account

007 $need = - $player

// Если же денег у игрока куры не клюют - переводим на станцию столько, сколько нужно чтобы счет сравнялся с нижним пределом.

008 else

009 $need = $account - $min

010 end

011 end

// Если на счете станции больше денег, чем положено верзним пределом - сбрасываем излишек на счет игрока. На станции остается денег ровно "под пробку".

012 skip if not $account > $max

013 $need = $account - $max

// Собственно, переводы денег: сколько переводим игроку - столько же снимаем со станции.

014 add money to player: $need

015 $need = - $need

016 $station -> add money: $need

// Возвращаем сумму - сколько денег переведено на счет станции. Соответственно, столько же сняли со счета игрока.

017 return $need

Найм менеджера на станцию (StM.install)

Аргументы:

Station - объект:станция;

min - число:нижний предел остатка на счете станции;

max - число:верхний предел остатка на счете станции.

Скрипт

// Блокируем глобальные переменные чтобы спокойно распоряжаться ими

001 @ = [THIS] -> call script 'ANS.lock' : LockName='StMlock' Pause=2000 Tries=0

// Защита от дурака. Если пилот указал верхний и нижний пределы в обратном порядке - меняем их местами.

003 if $min > $max

004 $i = $min

005 $min = $max

006 $max = $i

007 end

// Если пилот в качестве пределов счета указал отрицательные числа - устанавливаем пределы равными нулю.

009 skip if $max > 0

010 $max = 0

011 skip if $min > 0

012 $min = 0

// Получаем значения глобальных переменных

014 $StMnum = get global variable: name='StMnum'

015 $StMsts = get global variable: name='StMsts'

016 $StMtotal = get global variable: name='StMtotal'

017 $StMjmMin = get global variable: name='StMjmMin'

018 $StMjmMax = get global variable: name='StMjmMax'

019 $StMdiff = get global variable: name='StMdiff'

// В этом цикле мы за один проход по списку станций находим сразу две вещи. Во-первых, проверяем наличие станции в списке. Если станция в списке есть, ее индекс будет находиться в переменной i. Если станции в списке нет, переменная i будет иметь значение StMnum. Во-вторых, находим индекс первой из станций, расположенных в том же секторе что и новая, включаемая в список станция. Если такая станция обнаружена, ее индекс будет находиться в переменной j. Тогда при добавлении cтанции в общий список, станция добавится перед всеми другими станциями своего сектора. Если не нашлось станции из этого же сектора (если мы еще не нанимали менеджера ни на одну из станций в этом секторе), переменная j будет иметь значение 0. Тогда новая станция будет добавлена в начало списка станций.

021 $i = 0

022 $j = 0

023 $sector = $Station -> get sector

024 while $i < $StMnum

025 $st = $StMsts[$i]

026 $sec = $st -> get sector

027 skip if $sec != $sector

028 $j = $i

029 skip if $st != $Station

030 break

031 inc $i =

032 end

// Если переменная i имеет значение StMnum, то есть был проверен весь список и станция в нем не обнаружена - добавляем станцию в позицию списка, на которую указывает переменная j (она указывает либо на начало списка, либо на первую станцию из того же сектора, что и новая станция)

034 if $i == $StMnum

// Оператор insert <элемент> into array <массив> at index <индекс> сдвигает на одну позицию все элементы массива начиная с того, на который указывает индекс. На освободившееся место записывется новый элемент.

036 insert $Station into array $StMsts at index $j

037 insert 0 into array $StMtotal at index $j

038 insert 0 into array $StMdiff at index $j

039 insert $min into array $StMjmMin at index $j

040 insert $max into array $StMjmMax at index $j

// Поскольку в список была добавлена одна станция - увеличиваем общее количество станций на единицу.

041 inc $StMnum =

// Присваиваем глобальным переменным новые значения

043 set global variable: name='StMsts' value=$StMsts

044 set global variable: name='StMtotal' value=$StMtotal

045 set global variable: name='StMdiff' value=$StMdiff

046 set global variable: name='StMnum' value=$StMnum

// Записываем в лог игрока подтверждающее сообщение

048 write to player logbook: printf: pageid=2010 textid=70005, $Station, $min, $max, null, null

// Если после прохода по списку станций переменная i имеет значение, отличающееся от StMnum, это означает что наша станция уже есть в списке и добавлять ее не нужно - нужно только установить для нее новые пределы счета.

049 else

050 $StMjmMin[$i] = $min

051 $StMjmMax[$i] = $max

052 write to player logbook: printf: pageid=2010 textid=70006, $Station, $min, $max, null, null

053 end

// Здесь мы сохраняем глобальные переменные StMjmMin и StMjmMax. Это нужно делать вне зависимости от того, найдена была станция в списке - или нет. Вот почему эти две команды вынесены за пределы условного оператора if.

055 set global variable: name='StMjmMin' value=$StMjmMin

056 set global variable: name='StMjmMax' value=$StMjmMax

// Как обычно, не забываем снять блокировку с глобальных переменных. Мы свою работу сделали, сохранили их - теперьнужно дать возможность сделать свою работу другим скриптам.

058 set global variable: name='StMlock' value=[FALSE]

059 return null

С операторами записи в logbook игорока давайте разберемся подробнее.

Logbook

Игрок имеет свою ленту сообщений. Каждая запись в ленте имеет дату и пояснение - что это за текст (сообщение от кого-либо или же просто запись).

Из скрипта сообщение игроку можно отправить с помощью оператора send incoming message <строка> to player: display it=<флаг> из раздела (почему-то) Audio Commands. Если флаг установлен в TRUE, сообщение немедленно будет показано игроку прямо поверх кокпита. В любом случае, текст сообщения будет записан в logbook игрока.

Простую запись можно поместить в logbook с помощью одного из трех операторов раздела Logbook Commands:

1. write to player logbook <строка>

2. write to player logbook: printf: fmt=<строка формата>, <п1>, <п2>, <п3>, <п4>, <п5>

3. write to player logbook: printf: pageid=<число>, textid=<число>, <п1>, <п2>, <п3>, <п4>, <п5>

Первый оператор записывает фиксированную строку в logbook - безо всяких изменений.

Второй оператор позволяет записать в logbook строку, в определенные места которой можно подставить различные значения - числа, названия, имена и т.д. Собственно, строка формата - это то, что мы хотим записать в logbook. А параметры п1, п2, ..., п5 - это значения, которые мы хотим в строку подставить. Этих значений может не быть вообще (тогда строка просто будет записана без изменений) или же могут быть одно, два - до пяти включительно.

Чтобы в строке формата определить место для вставки параметра, в нужном месте строки следует вставить символ '%', за которым следуют один или несколько спецсимволов, поясняющих скриптовому движку какие дополнительные действия нужно совершить с параметром, прежде чем вставить его в строку формата.

Параметры в строку формата вставляются по очереди, в том порядке, в каком в строке формата встречаются символы '%' (если я явном виде не задан иной порядок).

На сегодня известны такие комбинации спецсимволов:

%s - просто в этом месте вставить в строку параметр, как он есть.

%d - вставить параметр как число. Лично мне пока не удалось обнаружить отличий от %s, поэтому я везде использую %s вместо %d.

%!ns - вставить в этом месте параметр номер n (а не тот, который должен тут стоять в порядке очереди).

%ns - в этом месте строка формата раздвигается ровно на n симолов, в освободившееся место записывается столько символов параметра, сколько поместится. Если параметр короче чем n символов, перед символами параметра в строку включается столько пробелов, сколько недостает до n. Таким образом параметр выравнивается в по правому краю отведенного ему места.

%-ns - действует так же, как и %ns, с той лишь разницей что параметр выравнивается по левому краю отведенного ему места.

Третий оператор записи сообщений очень похож на второй. Отличие в том, что строка формата не задана в явном виде в тексте скрипта. Она будет прочитана из обсуждавшихся ранее файлов вида XXnnnn.xml (440001.xml, 440002.xml, 440003.xml и т.д. - для английской версии игры). Параметр pageid задает номер страницы, параметр textid задает номер строки в этих файлах.

Каждый оператор создает отдельное сообщение. Предположим, наше сообщение имеет сложную структуру (или оно очень длинное) и нам неудобно выводить его одним оператором. Как быть в таком случае?

В таком случае нужно "набрать" большое сообщение из нескольких мелких. Делается это оператором сложения: msg = msg1 + msg2 + msg3 и т.д. Затем одним оператором выводим сообщение msg.

Очевидно, для создания частей сообщения требуются операторы записи в переменную, а не logbook. Такие операторы есть в разделе General Commands.

Это:

1. <переменная> = sprintf: fmt=<строка формата>, <п1>, <п2>, <п3>, <п4>, <п5>

2. <переменная> = sprintf: pageid=<число>, textid=<число>, <п1>, <п2>, <п3>, <п4>, <п5>

Они имеют тот же формат, что и операторы записи в logbook, но помещают строку результата не в лог игрока, а в указанную переменную.

Чтобы красиво оформить помещаемую в logbook строку, можно использовать специальные символы и тэги форматирования.

Пока что мне известен один нормально, стабильно работающий спецсимвол - это перевод строки ('\n').

Тэгов форматирования значительно больше.

Простые тэги:

[b] текст [/b] - текст будет отображен желтым цветом;

текст - текст будет отображен ярко-белым цветом;

[green]текст[/green] - текст будет отображен зеленым цветом;

[red]текст[/red] - текст будет отображен красным цветом;

[justify]текст[/justify] - текст будет отформатирован так, чтобы иметь ровным как левый, так и правый край;

[center]текст[/center] - текст будет отцентрован;

[left]текст[/left] - текст будет иметь ровный левый край;

[right]текст[/right] - текст будет иметь ровный правый край.

Еще имеются два специальных тэга:

[author]автор[author] - в сообщении в поле "от кого" будет указана строка "автор". Этот тэг должен быть самым первым (и единственным) в теле сообщения.

[text cols='число колонок' colwidth='ширина колонки' colspacing='расстояние

между колонками']текст[/text] - если этот тэг присутствует, он должен идти сразу за тэгом [author] (если тэг [author] также присутствует) или в самом начале тела сообщения. Закрывающий тэг [/text] безусловно обрывает текст сообщения. Параметры cols, colwidth и colspacing могут присутствовать или отсутствовать независимо друг от друга. В чем задается ширина колонки и расстояние между колонками - неясно. В режиме экрана 640x480 эти числа, похоже, совпадают с пикселями экрана.

Возвращаясь к нашему скрипту, становится понятно, что оператор

052 write to player logbook: printf: pageid=2010 textid=70006, $Station, $min, $max, null, null

считывает из страницы с идентификатором 2010 строку с идентификатором 70006 и использует ее как строку формата, подставляя в нее три параметра - Station, min и max.

Эта строка определена там же, где и наши собственные команды StM - в файле 440003.xml:

<t id="70005">Station manager hired to station %s\nLow boundary of station account: %s\nTop boundary of station account: %s\n</t>

Зачем такие сложности, почему бы не записать эту строку прямо в тексте скрипта?

Во-первых, в благословенном встроенном редакторе скриптов вам просто не удастся набрать символ '[' чтобы внести в строку тэги форматирования.

Во-вторых, и это гораздо важнее, мы можем создать для нашего скрипта файл 700003.xml с такой строкой:

<t id="70005">На станцию %s нанят новый менеджер\nНижнее ограничение для счета станции составляет %s кредитов,\nверхнее ограничение составляет [b]%s[/b] кредитов\n</t>

Если пользователь игры выбирает русскую локализацию - вместо файлов 44nnnn.xml игра будет читать файлы 70nnnn.xml, и наш скрипт волшебным образом заговорит по-русски. То же самое касается других языков.

Правда, при запросе параметров скрипта все равно будут выводиться строки подсказки, "забитые" в файл скрипта. Так что, как ни крути, все равно для полной локализации придется переписывать сами скрипты. Но, если позволить себе такую же расслабуху, какую позволили себе авторы игры - то вполне сойдет и так.

Включение всех существующих станций в список управления. Сканирование галактики.

Скрипт StM.install.all включает в список управления все существующие на данный момент станции игрока, устанавливая им всем одинаковые пределы счета.

Аргументы:

min - число:нижний предел остатка на счете каждой станции;

max - число:верхний предел остатка на счете каждой станции.

Текст скрипта:

// Сканируем галактику по секторам - сначала по столбцам, затем - по строкам. Начинаем с нижнего правого угла карты.

001 $i = get max sectors in x direction

002 while $i >= 0

003

004 $j = get max sectors in y direction

005 while $j >= 0

// Для каждой пары координат {x,y} пытаемся получить сектор. Поскольку не каждая такая пара указывает на сектор - стоит проверять результат перед использованием. Если мы сейчас этого не сделаем - ничего страшного не произойдет, все равно список станций игрока окажется пустым, но лучше сразу завести себе такую полезную привычку.

007 $sec = get sector from universe index: x=$i, y=$j

008 if $sec -> exists

// Сектор существует - получаем список станций игрока в этом секторе. Список будет помещен в массив sts. Размер массива нам неизвестен, чтобы узнать его используем оператор size of array.

009 $sts = $sec -> get player owned station array from sector

010 $nst = size of array $sts

// Если переменная nst равна нулю - это означает что в секторе sec нет ни одной станции игрока. В этом случае цикл не будет исполнен ни разу. Оператор уменьшения dec nst стоит в самом начале цикла по той причине, что nst одновременно используется и как счетчик элементов массива, и как указатель на эти элементы. Поскольку элементы массива нумеруются начиная с нуля, индекс последнего элемента массива всегда на единицу меньше общего числа элементов. Раз уж мы сканируем массив от конца к началу - нам нужно уменьшать счетчик элементов ПЕРЕД тем, как применять его в качестве указателя на последний элемент массива.

011 while $nst

012 dec $nst =

// Получаем станцию игрока из списка станций игрока в секторе

013 $st = $sts[$nst]

// Для полученной станции вызываем рассмотренный ранее скрипт StM.install с параметром Station, указывающим на эту станцию.

014 @ = [THIS] -> call script 'StM.install' : Select station=$st Low boundary of station account=$min Top boundary of station account=$max

015 end

// Здесь завершается обработка существующего сектора

016 end

// Переходим к следующему индексу в столбце карты галактики.

018 dec $j =

019 end

// Переходим к следующему индексу в строке карты галактики.

021 dec $i =

022 end

023 return null

Увольнение менеджера со станции

Аргумент:

Station - объект:станция.

Текст скрипта:

// Блокируем глобальные переменные

001 @ = [THIS] -> call script 'ANS.lock' : LockName='StMlock' Pause=2000 Tries=0

// Считываем значения глобальных переменных

003 $StMnum = get global variable: name='StMnum'

004

005 $StMsts = get global variable: name='StMsts'

006 $StMjmMin = get global variable: name='StMjmMin'

007 $StMjmMax = get global variable: name='StMjmMax'

008 $StMtotal = get global variable: name='StMtotal'

009 $StMdiff = get global variable: name='StMdiff'

// Ищем в списке станций ту, которую нас попросили удалить. Не факт, что мы ее найдем. Если мы ее не найдем, переменная-счетчик i будет равна StMnum - таково первое условие выхода из цикла. Если найдем - i будет содержать индекс станции в массиве StMsts.

011 $i = 0

012 while $i < $StMnum

013 $st = $StMsts[$i]

// Второе условие выхода из цикла - если найдена нужная станция.

014 skip if $st != $Station

015 break

016 inc $i =

017 end

// Если станция найдена - удаляем ее из списка станций, удаляем ее параметры из списков параметров станций, уменьшаем общее количество станций в списке, записываем новые значения глобальных переменных, оставляем игроку соответствующее сообщение в логе.

019 if $i < $StMnum

020 remove element from array $StMsts at index $i

021 remove element from array $StMdiff at index $i

022 remove element from array $StMjmMax at index $i

023 remove element from array $StMjmMin at index $i

024 remove element from array $StMtotal at index $i

025

026 dec $StMnum =

027 set global variable: name='StMnum' value=$StMnum

028

029 set global variable: name='StMsts' value=$StMsts

030 set global variable: name='StMdiff' value=$StMdiff

031 set global variable: name='StMjmMax' value=$StMjmMax

032 set global variable: name='StMjmMin' value=$StMjmMin

033 set global variable: name='StMtotal' value=$StMtotal

034

035 write to player logbook: printf: pageid=2010 textid=70007, $Station, null, null, null, null

036 end

// В любом случае - снимаем блокировку с глобальных переменных.

038 set global variable: name='StMlock' value=[FALSE]

039 return null

Отчет о движении денег (StM.report.all)

Скрипт:

// Как обычно, начинаем с блокировки глобальных переменных

001 @ = [THIS] -> call script 'ANS.lock' : LockName='StMlock' Pause=2000 Tries=0

002

003 $StMsts = get global variable: name='StMsts'

004 $StMnum = get global variable: name='StMnum'

005 $StMtotal = get global variable: name='StMtotal'

006 $StMdiff = get global variable: name='StMdiff'

// Для красоты отчет будет иметь рамочку из сиволов '='. Здравствуйте, шестидесятые...

008 $rep = sprintf: pageid=2010 textid=70000, null, null, null, null, null

// В цикле проходим по списку станций. Начинаем с того, что показываем и запоминаем название сектора первой станции в списке. Для каждой последующей станции проверяем - совпадает ли название ее сектора с тем, который мы держим "в уме". Если не совпадает - показываем название нового сектора и запоминаем его в качестве текущего. И так далее...

010 $oldsec = null

// В переменной s будем накапливать общую сумму денег, переведенную за все время со всех станций.

011 $s = 0

// В переменной d будем накапливать общую сумму денег, переведенную со всех станций с момента выдачи последнего отчета (последнего перед этим).

012 $d = 0

// i - индекс очередной станции в списке.

013 $i = 0

014 while $i < $StMnum

015 $st = $StMsts[$i]

016

017 $newsec = $st -> get sector

018 if $newsec != $oldsec

019 $oldsec = $newsec

// Строка с идентификатором 70003 содержит шаблон для показа названия сектора.

020 $rl = sprintf: pageid=2010 textid=70002, $newsec, null, null, null, null

// Добавляем к отчету строчку с названием сектора.

021 $rep = $rep + $rl

022 end

// Здесь мы запоминаем сумму денег, переведенную со счета станции на счет игрока со времени последнего отчета - а затем обнуляем ее.

024 $total = $StMtotal[$i]

025 $diff = $StMdiff[$i]

026 $StMdiff[$i] = 0

027 $s = $s + $total

028 $d = $d + $diff

// Благословенная версия 1.4 позволяет нам (наконец-то!) показать имя станции.

030 $stname = $st -> get name

// Строка с идентификатором 70003 содержит шаблон для выдачи сведений по одной конкретной станции.

031 $rl = sprintf: pageid=2010 textid=70003, $stname, $total, $diff, null, null

// Добавляем к отчету строчку с данными по текущей станции.

032 $rep = $rep + $rl

// Переходим к следуюшей станции в списке.

034 inc $i =

035 end

// Под отчетом подводим красивую черту в стиле ретро - из символов '='.

037 $rl = sprintf: pageid=2010 textid=70000, null, null, null, null, null

038 $rep = $rep + $rl

// Отбиваем несколько переводов строки - чтобы в лог-файле отчеты не сливались.

039 $rl = sprintf: pageid=2010 textid=70004, null, null, null, null, null

040 $rep = $rep + $rl

// Сохраняем в глобальной переменной очищенный массив сумм, переведенных со времени последнего (теперь уже вот этого самого) отчета.

042 set global variable: name='StMdiff' value=$StMdiff

// Считываем из глобальной переменной дату предыдущего отчета и приводим ее к читаемому виду.

044 $since = get global variable: name='StMlastrep'

045 @ $since = [THIS] -> call script 'ANS.format.date' : ticks=$since

// Получаем и приводим к читаемому виду текущую игровую дату. Попутно сохраняем текущую дату в качестве даты последнего отчета (что соответствует действительности).

074 $date = playing time

048 set global variable: name='StMlastrep' value=$date

049 @ $date = [THIS] -> call script 'ANS.format.date' : ticks=$date

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

050 $head = sprintf: pageid=2010 textid=70001, $date, $since, $s, $d, null

// Разблокируем глобальные переменные - мы уже внесли все необходимые изменения.

052 set global variable: name='StMlock' value=[FALSE]

// Заголовок отчета пишем в logbook игрока.

054 write to player logbook $head

// К лог-файлу дописываем сначала заголовок, а затем и тело отчета.

055 write to log file #700 append=[TRUE] value=$head

056 write to log file #700 append=[TRUE] value=$rep

057 return null

Полный текст файла 440003.xml

<?xml version="1.0" encoding="UTF-8" ?>

<language id="44">

<page id="2010" title="Commands" descr=" ">

<t id="1110">Hire manager to this station</t>

<t id="1111">Hire manager to all stations</t>

<t id="1112">Industry profit and loss statement</t>

<t id="1113">Set contigency fund</t>

<t id="1119">Fire manager from this station</t>

<t id="70000">=============================================================================\n</t>

<t id="70001">Industry Profit and Loss Statement\n\nDate: %15s\nSince: %15s\n\nTotal Profit: %15s\nSince Last Report: %15s\n\n</t>

<t id="70002">---- %-40s -------------------------------\n</t>

<t id="70003">%-43s %15s %15s\n</t>

<t id="70004">\n\n\n\n\n</t>

<t id="70005">Station manager hired to station %s\nLow boundary of station account: %s\nTop boundary of station account: %s\n</t>

<t id="70006">Set new account boundaries at station %s -\n%s for low and %s for top\n</t>

<t id="70007">Station manager fired from station %s\n</t>

</page>

<page id="2011" title="Commands" descr=" ">

<t id="1110">StM</t>

<t id="1111">StM</t>

<t id="1112">StM</t>

<t id="1113">StM</t>

<t id="1119">StM</t>

</page>

</language>

Последние замечания

Этот скрипт обладает одним врожденным недостатком. Вполне возможна такая ситуация, когда станции, стоящие в начале списка, выгребают со счета игрока всю наличность, и станциям в середине списка ничего не остается. В то же время на счетах станций в конце списка может оставаться излишек денег, который как раз пригодился бы для покрытия недостачи на счетах станций из середины списка.

Решение простое - делать подряд два прохода по списку станций. На первом проходе снимать излишки, на втором - восполнять недостачи. Но стоит ли овчинка выделки? Лично я считаю - не стоит. Впрочем, если вы заинтересовались описанием этого скрипта в учебных целях - вам есть смысл попробовать модифицировать его самостоятельно. Полезная тренировка.


"Учимся писать скрипты" разбираем скрипт Корабль-Склад

Статья приведена в оригинальном тексте автора

Учимся писать скрипты

Попытаемся разобраться в работе скрипта warehouse.xml «Корабль-склад» версии 2.0 (см. собрание скриптов пилотов). Мы с вам пройдем весь путь: от составления алгоритма до написания скрипта, реализующего выбранный алгоритм. Поехали!

Задача: заставить корабль следить за состоянием склада заданного товара станции приписки и поддерживать определенное, заданное пользователем, количество товара на складе, регулируя его за счет своего трюма.

Нужно сказать, что четко сформулированная задача – это 20% успеха дела. Необходимо точно представлять, ЧТО вы хотите сделать, чтобы составить нормальный алгоритм программы. Кроме этого, всегда нужно стремиться, чтобы скрипт:

1. был по-возможности небольшим, а если это по характеру задачи невозможно – то хорошо структурированным, иначе мы начнем в нем теряться;

2. был универсальным, если это требуется;

3. учитывал самые разные возникающие ситуации;

4. содержал некоторую защиту от некорректных действий пользователя;

5. не содержал кода, который мог бы привести к зависанию игры или имел от этого защиту;

6. не загружал игру бесконечными сложными вычислениями.

Разумеется, все это сложно совместить, но нужно стараться…

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

1. Очевидно, нам потребуются некоторые начальные условия для корабля, которые задает пользователь. Исходя из условий поставленной задачи, мы должны задать кораблю станцию, товар на станции, с которым он будет работать, и количество этого товара, которое корабль будет поддерживать. На последнем пункте остановимся и подумаем: каким должно быть это количество? Известно, что разные станции хранят различное количество различного товара. Если мы будем задавать абсолютное количество товара, то мы можем легко ошибиться, т.к. в этом случае мы должны твердо знать, сколько нужного нам товара хранит данная станция. Поэтому лучше задать относительное кол-во товара, например в процентах от максимального объема склада. Это позволит нам не думать о типе товара и фактическом объеме склада. И это будет правильный и универсальный подход к делу.

2. После получения условий начинаем действовать. Но прежде нужно кое-что проверить – вдруг пользователь задал некорректные условия? Ведь это может привести к неправильной работе и даже (не дай бог) к зависанию игры. Прежде всего необходимо проверить, кому принадлежит станция – игроку или другой расе. Если станция наша, то все в порядке, можно продолжать. Если же нет – дальнейшая работа бесполезна и нужно прервать выполнение скрипта.

3. Далее нужно проверить, может ли корабль перевозить/хранить заданный товар. Если да, то все в порядке, можно продолжать. Если же нет – дальнейшая работа также бесполезна и нужно прервать выполнение скрипта.

4. Все, больше ничего критического для нормальной работы скрипта пользователь не задал, можно действительно начинать действовать. Назначим станцию базой приписки для нашего корабля. Это будет удобно для пользователя при просмотре собственности.

5. В момент получения команды корабль может находится далеко от станции, и это нужно предусмотреть. Если это так, надо дать команду кораблю лететь на станцию, а если мы уже пристыкованы к этой станции, разумеется, лететь никуда не надо.

6. Дальше нам нужно получить из значения относительного лимита абсолютное, ведь относительный лимит удобен только для игрока, но для корабля он решительно не подходит. Для этого нам потребуются некоторые несложные вычисления.

7. Теперь можно приступать к выполнению главной задачи: следить за количеством товара на станции. Поскольку эта задача постоянна, выполнять мы ее будем циклически, пока кораблю не поступит другая команда. Для этого нужно организовать цикл и внутри цикла производить действия по загрузке/разгрузке.

8. Что делать внутри цикла? Нужно проверять, сколько товара есть на складе, сравнивать это фактическое кол-во с нашем лимитом, если товара больше, то погружаем излишек в трюм, если недостаток – то выгружаем товар на склад до достижения лимита.

Вот и все. Несложно, не правда ли? Попробуем теперь воплотить все это на языке игры.

Arguments

1: home.ware , Перем/Станция и товар , 'Select station and ware'

2: perc , Число , 'Input warehouse percent'

Зададим начальные условия для скрипта в разделе аргументов. Скриптовый движек игры позволяет задать переменную-массив из станции и ее товара. Это удобнее, чем отдельные переменные, потому как в процессе выбора товара запрашиваться будет только товар из списка товаров станции, а не вываливаться полный список всех существующих товаров. Назовем эту переменную-аргумент $home.ware. Процентный лимит будет называться у нас $perc.

Source Text

001 $ship = [THIS]

Присвоим переменной $ship указатель на объект (корабль), получивший команду. Это для нашего удобства.

002
003 $ware = $home.ware[0]
004 $home = $home.ware[1]

Присвоим переменной $ware значение ячейки номер 0 массива $home.ware (это наш товар), а переменной $home значение ячейки номер 1 того же массива (это станция).

005
006 $owner = $home -> get owner race

Получим в переменную $owner расу владельца станции $home.

007 skip if $owner == Player
008 return null

Проверим, совпадает ли раса-владелец $owner с расой Player, или, попросту говоря, принадлежит ли она игроку. Если нет, то прерываем скрипт.

010 skip if $ship -> can transport ware $ware
011 return null

Проверим, может ли корабль $ship перевозить товар $ware. Если нет, то прерываем скрипт.

013 $ship -> set homebase to $home

Установим для корабля $ship станцию $home в качестве станции приписки.

014

015 set script command: COMMAND_TYPE_TRADE_10

Эта команда позволит команде «Складировать товар» отображаться в информанционных окнах корабля, и мы будем видеть, ЧТО корабль делает. Это чистой воды сервисная команда. А происходит это потому, что в инициирующем скрипте команда-константа COMMAND_TYPE_TRADE_10 завязана на наш скрипт.

016
017 * fly to home if we are not at home

Это просто комментарий «летим домой если мы не дома».

018 skip if $home == [ENVIRONMENT]
019 @ = $ship -> fly to home base

Проверим, совпадает ли окружение [ENVIRONMENT] нашего корабля со станцией $home. В данном случае это наиболее простой способ узнать, пристыкован ли корабль к интересующей нас станции. Если окружение не совпадает, это значит, что корабль находится в космосе, пристыкован к другой станции или кораблю – неважно. Итак, если он не пристыкован, то даем команду кораблю $ship лететь на станцию приписки.

020 skip if $home -> exists
021 return null

Проверим, существует ли станция $home или нет. Ведь ее могли уничтожить, пока мы летели! Если же мы никуда не летели, то это чистая формальность. Вообщем, если станции нет, прекращаем работу скрипта.

022
023 $max = $home -> get max. store amount of ware $ware
024 $max = $max * $perc / 100

В переменную $max в строке 023 мы получаем максимальное кол-во товара $ware, которое может храниться на станции $home. В строке 024 мы присваиваем все той же переменной $max абсолютное значение лимита товара, восстанавливая его из указанного игроком процента в переменной $perc. Не будем вдаваться в арифметику второго класса – думаю, механизм всем понятен.

025
026 while [TRUE]

Организуем «вечный» цикл (для этого в качестве условия оператору while задается постоянное логическое значение «правда»), внутри которого будем заниматься нашим контролем лимита.

027 $quantity = $home -> get amount of ware $ware in cargo bay

Получаем в переменную $quantity количество товара $ware, которое в данный момент хранится на складе станции $home.

028 $quantity = $max - $quantity

Присваиваем переменной $quantity разницу нашего лимита $max и того же количества на складе $quantity.

Обратите внимание, как и в строках 023 и 024 мы не заводим лишнюю переменную, а используем уже существующие. Так вполне можно делать, так как это изменяющееся (динамическое) значение и нет нужды его долго хранить. К тому же такой прием экономит память. Итак, после этой строки переменная $quantity вместо текущего количества товара на станции стала хранить количество товара, которым нам нужно обменяться со станцией! Это количество по понятным причинам может быть либо положительным, либо отрицательным. Поняли, почему? Прикиньте возможные ситуации на бумажке и поразмыслите.

029 if $quantity > 0
030 = $ship -> unload $quantity units of $ware
031 else
032 $quantity = - $quantity
033 = $ship -> load $quantity units of $ware
034 end

Итак, если количество положительное ($quantity > 0), то выполняется строка 030, где корабль $ship пытается выгрузить $quantity единиц товара $ware. В противном случае ($quantity<=0) выполняются строки 032 и 033, где мы сначала инвертируем знак переменной $quantity (из отрицательного числа делаем такое же положительное, 0 останется неизменным), а потом пытаемся загрузить в корабль это количество. Строка 034 – конец оператора условия if. Обратите внимание – мы не занимаемся никакими вычислениями, учитывающими остаток свободного места на корабле! На самом деле за нас это делают команды load и unload. Они сами контролируют корректность процессов и ничего недопустимого не сделают. Кстати, по такому же принципу действуют торговые команды sell и buy, в которых задействованы еще и деньги. Здесь мы придерживаемся святого принципа универсальности: нам совершенно не важно, сколько свободного места на корабле и как оно изменяется.

035 @ = wait randomly from 10000 to 15000 ms

036 end

В строке 035 мы выдерживаем паузу в 10-15 секунд, а строка 036 – конец цикла.

037
038 return null

Все, конец скрипта.


Делаем свой корабль из стандартных частей. (автор ZAV)

*статья приведена в оригинальном тексте автора.

Хотел научиться моддингу – читай.

Для начала ссылки, где можно всего понемногу вычитать:

Моддинг связь TShips и моделей кораблей

Структура Scene файла

FAQ: Скриптописание

Как можно создать свой корабль:

1. Воспользоваться информацией, которую дал Breeze в первой указанной теме. Т.е. рисовать все в 3D MAX-е, экспортировать нарисованное спец скриптом в bod.

2. Собрать кораблик из стандартных запчастей (как делал я).

Второй способ подробнее.

Сразу оговорюсь. Редактировал в обычном блокноте.

Рассмотрим на примере моего мода.

В папке CUT хранятся SCENE файлы, в которых написано, куда и какую запчасть надо поставить, чтобы был полноценный корабль. Т.е. здесь описывается вся визуальная часть корабля. Файлы bob – бинарный вариант SCENE, в нем ничего не разберешь. Pbd – закодированный вариант того же SCENE. Bod – SCENE файл в обычной форме, пригожей для редактирования (поэтому я и использовал этот формат).

В папке v хранятся отдельные запчасти к кораблям, станциям и всему видимому в X2. Просмотреть их можно утилитой BODviewer.exe. Сразу уточню тот факт, что я хоть и использовал стандартные запчасти, но две из них я скопировал и сохранил под другими именами (15010.bod и 15011.bod), замасштабировал (т.е. изменил их размер до нужного), для чего поменял числа в строке:

115000; / Automatic Object Size.

В папке scripts хранятся скрипты, инициализирующие

1появление корабля на Аргонской верфи

2название

3описание корабля.

В папке t хранятся файлы с названием и описанием корабля.

В папке types:

TBullets.txt, TLaser.txt – в этих файлах информация по мощности, скорости поворота и т.п. всего оружия (кроме ракет). Если надо – могу подробнее.

TCockpits.txt – частичное назначение – хранить тип поддерживаемого тарелью оружия.

TShips.txt – по сути в нем хранится вся информация (основная) по характеристикам корабля. Подробнее читай в первой данной ссылке.

Теперь собственно основное.

Файл SCENE 04101.bod

Названия частей подписаны, думаю разберешься.

Вначале каждой строки стоит P с номером. Эти номера позже пригодятся для приписывания кокпитам пушек.

А само создание кораблей сводится к добавлению необходимых запчастей и редактированию их размещения относительно центра. Чтобы понять, можешь «поиграться» с координатами в этом файле.

Что непонятно, читай в форумах по ссылкам или задавай вопросы.

/===============================================================

/ 3D Scene Information from 3ds file: f:\src\xgold\data\meshes\04101.3ds

/===============================================================

VER: 2;

/ +R -L +U -D +F -B Angel Pitch Yaw Roll Time(ms)

P 0; B 00940; { 2; 0; 0; 0; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- reference-body for ships -Точка отсчета (т.е. 0)

P 1; B 00806 – номер bod файла этой запчасти в папке v; C 1; { 2; 0 – координата x; 100000 - y; -40000 - z; 0.0000 – множитель угла поворота; 0.0000; 0.0000; 0.0000 – углы поворота по соответствующим координатам; -1; -1; } // 0 /- Argon M2 - Bridge - Кокпит

P 2; B 00919; C 1; { 2; 300; 65000; 160000; 0.5000; 0.0000; 0.0000; 1.0000; -1; -1; } // 0 /- gun tower - Bridge

P 3; B 00919; C 1; { 2; 0; 65200; 160000; 0.7500; 0.0000; 0.0000; 1.0000; -1; -1; } // 0 /- gun tower - Bridge

P 4; B 00919; C 1; { 2; 0; 64800; 160000; 0.2500; 0.0000; 0.0000; 1.0000; -1; -1; } // 0 /- gun tower - Bridge

P 5; B 00919; C 1; { 2; -300; 65000; 160000; 0.0000; 0.0000; 0.0000; 1.0000; -1; -1; } // 0 /- gun tower - Bridge

P 6; B 00939; C 2; { 2; 39000; 14000; 340000; 0.0000; 0.0000; 0.0000; 0.0000; 1; 1; } // 0 /- Turret - front

P 7; B 00708; C 2; { 2; 59500; 10000; 345700; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- gun tower - front

P 8; B 00708; C 2; { 2; 40500; 10000; 345700; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- gun tower - front

P 9; B 00708; C 2; { 2; -40500; 10000; 345700; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- gun tower - front

P 10; B 00708; C 2; { 2; -59500; 10000; 345700; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- gun tower - front

P 11; B 00939; C 3; { 2; 0; 10000;-322000; 0.5000; 0.0000; 1.0000; 0.0000; 1; 1; } // 0 /- Turret - back

P 12; B 00708; C 3; { 2; 28000; 16000;-329000; 0.5000; 0.0000; 1.0000; 0.0000; -1; -1; } // 0 /- gun tower - back

P 13; B 00708; C 3; { 2; 14000; -16000;-329000; 0.5000; 0.0000; 1.0000; 0.0000; -1; -1; } // 0 /- gun tower - back

P 14; B 00708; C 3; { 2; -14000; -16000;-329000; 0.5000; 0.0000; 1.0000; 0.0000; -1; -1; } // 0 /- gun tower - back

P 15; B 00708; C 3; { 2; -28000; 16000;-329000; 0.5000; 0.0000; 1.0000; 0.0000; -1; -1; } // 0 /- gun tower - back

P 16; B 00939; C 4; { 2; 214000; -27500; -145000; 0.2500; 0.0000; 1.0000; 0.0000; 1; 1; } // 0 /- Turret - right

P 17; B 00708; C 4; { 2; 204500; -35000; -90000; 0.2500; 0.0000; 1.0000; 0.0000; -1; -1; } // 0 /- gun tower - right

P 18; B 00708; C 4; { 2; 212000; -31000; -117500; 0.2500; 0.0000; 1.0000; 0.0000; -1; -1; } // 0 /- gun tower - right

P 19; B 00708; C 4; { 2; 216000; -23000; -172500; 0.2500; 0.0000; 1.0000; 0.0000; -1; -1; } // 0 /- gun tower - right

P 20; B 00708; C 4; { 2; 214500; -19000; -200000; 0.2500; 0.0000; 1.0000; 0.0000; -1; -1; } // 0 /- gun tower - right

P 21; B 00939; C 5; { 2;-214000; -27500; -145000; 0.2500; 0.0000;-1.0000; 0.0000; 1; 1; } // 0 /- Turret - left

P 22; B 00708; C 5; { 2;-204500; -35000; -90000; 0.2500; 0.0000;-1.0000; 0.0000; -1; -1; } // 0 /- gun tower - left

P 23; B 00708; C 5; { 2;-212000; -31000; -117500; 0.2500; 0.0000;-1.0000; 0.0000; -1; -1; } // 0 /- gun tower - left

P 24; B 00708; C 5; { 2;-216000; -23000; -172500; 0.2500; 0.0000;-1.0000; 0.0000; -1; -1; } // 0 /- gun tower - left

P 25; B 00708; C 5; { 2;-214500; -19000; -200000; 0.2500; 0.0000;-1.0000; 0.0000; -1; -1; } // 0 /- gun tower - left

P 26; B 00939; C 6; { 2; 0; 110000; -52000; 0.2500;-1.0000; 0.0000; 0.0000; 1; 1; } // 0 /- Turret - top

P 27; B 00708; C 6; { 2; 85000; 112000; -8000; 0.2500;-1.0000; 0.0000; 0.0000; -1; -1; } // 0 /- gun tower - top

P 28; B 00708; C 6; { 2; -85000; 112000; -8000; 0.2500;-1.0000; 0.0000; 0.0000; -1; -1; } // 0 /- gun tower - top

P 29; B 00708; C 6; { 2; 82000; 118500; -272900; 0.2500;-1.0000; 0.0000; 0.0000; -1; -1; } // 0 /- gun tower - top

P 30; B 00708; C 6; { 2; -82000; 118500; -272900; 0.2500;-1.0000; 0.0000; 0.0000; -1; -1; } // 0 /- gun tower - top

P 31; B 00939; C 7; { 2; 0; -75000; -210000; 0.2500; 1.0000; 0.0000; 0.0000; 1; 1; } // 0 /- Turret - bottom

P 32; B 00708; C 7; { 2; 56500; -37000; 100000; 0.2500; 1.0000; 0.0000; 0.0000; -1; -1; } // 0 /- gun tower - bottom

P 33; B 00708; C 7; { 2; -56500; -37000; 100000; 0.2500; 1.0000; 0.0000; 0.0000; -1; -1; } // 0 /- gun tower - bottom

P 34; B 00708; C 7; { 2; 59250; -57400;-272900; 0.2500; 1.0000; 0.0000; 0.0000; -1; -1; } // 0 /- gun tower - bottom

P 35; B 00708; C 7; { 2; -59250; -57400;-272900; 0.2500; 1.0000; 0.0000; 0.0000; -1; -1; } // 0 /- gun tower - bottom

P 36; B 00935; { 2; -50000; 20000; 90000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- part

P 37; B 00935; { 2; 68000; 0; -175000; 0.5000; 0.0000; 1.0000; 0.0000; -1; -1; } // 0 /- part

P 38; B 00935; { 2; -68000; 0; -175000; 0.5000; 0.0000; 1.0000; 0.0000; -1; -1; } // 0 /- part

P 39; B 00935; { 2; 68000; 0; -40000; 0.5000; 0.0000; 1.0000; 0.0000; -1; -1; } // 0 /- part

P 40; B 00935; { 2; -68000; 0; -40000; 0.5000; 0.0000; 1.0000; 0.0000; -1; -1; } // 0 /- part

P 41; B 15011; { 2; 0; -10000; 155000; 0.5000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- part

P 42; B 00956; { 2; 0; 85000;-150000; 0.5000; 1.0000; 0.0000; 0.0000; -1; -1; } // 0 /- start pad of Teladi M1

P 43; B 15010; { 2; 100000; 10000;-100000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- part

P 44; B 15010; { 2; -100000; 10000;-100000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- part

P 45; B 00935; { 2; 50000; 20000; 90000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- part

P 46; B 00942; { 2; 0; 35000;-252500; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- part

P 47; B 00942; { 2; 0; -35000;-252500; 0.5000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- part

P 48; B 15011; { 2; 50000; 35000; 220000; 1.0000; 0.0000; 0.0000; 0.5000; -1; -1; } // 0 /- my part

P 49; B 15011; { 2; -50000; 35000; 220000; 1.0000; 0.0000; 0.0000; 0.5000; -1; -1; } // 0 /- my part

P 50; B 00935; { 2; 0; 30000; -30000; 0.5000; 0.0000; 1.0000; 0.0000; -1; -1; } // 0 /- part

P 51; B 00811; { 2; 0; 125000;-130000; 0.0000; 0.0000; 0.0000; 0.0000; 5000; 1; } // 0 /- Argon M2 - radar dish

{18; 0.5000; 0.0000; 1.0000; 0.0000; 5000; 2; } // 1 / - key frame

{18; 0.5000; 0.0000; 1.0000; 0.0000; -1; -1; } // 2 / - key frame – анимация поворота радара.

P 52; B 00929; { 2; 0; 60200; 34000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- part

P 53; B 00911; { 2; 0; 65000; 155000; 0.2500; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- Thruster - Split M5

P 54; B 00810; { 2; 70000; 110000;-150000; 0.5000; 0.0000; 1.0000; 0.0000; -1; -1; } // 0 /- Argon M2 - Sensor Array

P 55; B 00810; { 2; -70000; 110000;-150000; 0.5000; 0.0000; 1.0000; 0.0000; -1; -1; } // 0 /- Argon M2 - Sensor Array

P 56; B 00079; { 2; 0; 95000;-173000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- outer dock

P 57; B 00818; { 2; -50000; 20000; 220000; 0.5000; 0.0000; 1.0000; 0.0000; -1; -1; } // 0 /- ribbed long tube

P 58; B 00818; { 2; 50000; 20000; 220000; 0.500; 0.0000; 1.0000; 0.0000; -1; -1; } // 0 /- ribbed long tube

/P 60; B 00078; { 2; 91000; 27500; 364000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2; -91000; 27500; 364000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2; 91000; 27500; 222000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2; -91000; 27500; 222000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2; 116000; 26000; 66000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2;-116000; 26000; 66000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2; 116000; -26000; 66000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2;-116000; -26000; 66000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2; 116000; 26000;-105000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2;-116000; 26000;-105000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2; 116000; -26000;-105000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2;-116000; -26000;-105000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2; 76000; 66000;-200000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2; -76000; 66000;-200000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2; 76000; -66000;-200000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2; -76000; -66000;-200000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2; 102000; 37000;-292000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2;-102000; 37000;-292000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2; 102000; -37000;-292000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2;-102000; -37000;-292000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2; 24000; 55000; 90000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2; -24000; 55000; 90000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2; 24000; -39000; 160000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2; -24000; -39000; 160000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2; 0; 43000; 150000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

P 60; B 00078; { 2; 0; -59000; 50000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

P 60; B 00078; { 2; 0; 113000; -45000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2; 0; 65000;-297500; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

/P 60; B 00078; { 2; 0; -65000;-297500; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, red

P 70; B 10327; { 2; 0; 75000; -191000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, blue

P 70; B 10327; { 2; 0; 75000; -198000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, blue

P 70; B 10327; { 2; 0; 75000; -205000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, blue

P 70; B 10327; { 2; 0; 75000; -212000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, blue

P 70; B 10327; { 2; 0; 75000; -219000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, blue

P 70; B 10327; { 2; 0; 75000; -226000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, blue

P 70; B 10327; { 2; 0; 75000; -233000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, blue

P 70; B 10327; { 2; 0; 75000; -240000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, blue

P 70; B 10327; { 2; 0; 75000; -247000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, blue

P 70; B 10327; { 2; 0; 75000; -254000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, blue

P 70; B 10327; { 2; 0; 75000; -261000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, blue

P 70; B 10327; { 2; 0; 75000; -268000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, blue

P 70; B 10327; { 2; 0; 75000; -275000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, blue

P 70; B 10327; { 2; 0; 75000; -282000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, blue

P 70; B 10327; { 2; 0; 75000; -289000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, blue

P 70; B 10327; { 2; 0; 75000; -296000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, blue

P 70; B 10327; { 2; 0; 75000; -303000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, blue

P 70; B 10327; { 2; 0; 75000; -310000; 0.0000; 0.0000; 0.0000; 0.0000; -1; -1; } // 0 /- position light, blue – посадочные огни

P 99; B 10320; { 2; 7000; 39000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 20000; 39000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 33000; 39000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 46000; 36500;-277000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 59000; 34000;-269500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 72000; 31500;-262000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 85000; 29000;-254500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 98000; 26500;-247000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 7000; 34500;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 20000; 34500;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 33000; 34500;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 46000; 32250;-277000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 59000; 30000;-269500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 72000; 27750;-262000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 85000; 25500;-254500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 98000; 23250;-247000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 7000; 30000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 20000; 30000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 33000; 30000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 46000; 28000;-277000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 59000; 26000;-269500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 72000; 24000;-262000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 85000; 22000;-254500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 98000; 20000;-247000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -7000; 39000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -20000; 39000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -33000; 39000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -46000; 36500;-277000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -59000; 34000;-269500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -72000; 31500;-262000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -85000; 29000;-254500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -98000; 26500;-247000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -7000; 34500;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -20000; 34500;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -33000; 34500;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -46000; 32250;-277000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -59000; 30000;-269500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -72000; 27750;-262000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -85000; 25500;-254500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -98000; 23250;-247000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -7000; 30000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -20000; 30000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -33000; 30000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -46000; 28000;-277000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -59000; 26000;-269500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -72000; 24000;-262000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -85000; 22000;-254500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -98000; 20000;-247000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 7000; -39000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 20000; -39000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 33000; -39000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 46000; -36500;-277000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 59000; -34000;-269500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 72000; -31500;-262000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 85000; -29000;-254500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 98000; -26500;-247000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 7000; -34500;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 20000; -34500;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 33000; -34500;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 46000; -32250;-277000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 59000; -30000;-269500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 72000; -27750;-262000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 85000; -25500;-254500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 98000; -23250;-247000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 7000; -30000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 20000; -30000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 33000; -30000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 46000; -28000;-277000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 59000; -26000;-269500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 72000; -24000;-262000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 85000; -22000;-254500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; 98000; -20000;-247000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -7000; -39000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -20000; -39000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -33000; -39000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -46000; -36500;-277000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -59000; -34000;-269500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -72000; -31500;-262000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -85000; -29000;-254500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -98000; -26500;-247000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -7000; -34500;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -20000; -34500;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -33000; -34500;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -46000; -32250;-277000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -59000; -30000;-269500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -72000; -27750;-262000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -85000; -25500;-254500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -98000; -23250;-247000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -7000; -30000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -20000; -30000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -33000; -30000;-284500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -46000; 28000;-277000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -59000; 26000;-269500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -72000; 24000;-262000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -85000; 22000;-254500; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator

P 99; B 10320; { 2; -98000; 20000;-247000; 0.0000; 0.0000; 0.0000;-1.0000; -1; -1; } // 0 /- particle generator – двигатели и их анимация

ZAV


Связь Tships и моделей кораблей.

*статья приведена в оригинальном тексте автора.

Моддинг: связь TShips и моделей кораблей

Эта инфа может быть полезна тем кто собирается заниматся конкретно моддингом кораблей, и не хочет идти по бескрайней пустыне чисел используя лишь УМНТ, высасывая по пути жалкие капли данных из скудных официальных источников информации :D . Поэтому я накидал тут парочку описаний - в первой части поверхостно описал формат модели корабля, а во второй формат файла TShips.

Для комфортной работы нужны(желательны):

1) Что-нибудь типа Windows Commander, Volkov commander :) или короче любую удобную вам оболочку.

2) 3DSMAX 5/6 + экспортный плюгин от Egosoft (в комлекте с ModderKit)

3) Сам ModderKit (в нём помимо плюгина для макса, утилит для распаковки/упаковки dat/pck/pbd есть ещё документация, реально полезная для создания своих собственных моделей в МАX'е)

4) Желательно иметь X2 Object Modder (замечательная программа, спасибо Dimaxx'у за неё)

5) Неофициальные утилиты распаковки/упаковки (есть версии опять же made by Dimaxx, и другие не менее полезные утилиты от Пилотов)

6) Просто необходимо иметь X2 BOD viewer - made by UrQuan & Dimaxx - программу, позволяющую со всеми удобствами просматривать модели кораблей!

7) Cкрипт конвертации bod->max для 3DSMAX - made by altor

ЧАСТЬ 1 - формат игровой модели корабля.

Всё связанное с моделями в игре лежит в двух папках - V и CUT.

Папка V - это как бы "склад запчастей" - руки, ноги, головы, хвосты и т.д..

Папка CUT - в ней лежит набор "схем-чертежей" по которым собираются запчасти, которые можно взять из папки V.

Модели поделены на три типа - body,scene,combined.

Body - это тот тип файлов, что лежат в папке V. Проектируя body-модель мы проектируем запчасть, имеющую геометрические размеры, на неё можно накладывать текстуры, короче говоря все свойства модели-мэша экспортируемые из МАХ'а в игру можно узнать почитав X2_GFX_Modding.pdf идущий в комплекте с ModderKit'ом.

scene - это те файлы, что находятся в папке CUT. Создавая scene-модель мы создаём полноценный игровой объект, именно scene-файлами и представлены все корабли, станции, короче всё что мы видим в игре. В scene-модели выставляются координаты для body-запчастей и их направленность, и ещё анимация(просто изменение направленности). Ниже на примерах объясню подробнее.

combined - комбинированный тип scene+bodies. Этот тип моделей используется в основном для скриптовых сцен-мультиков, разработчики не советуют использовать его ни для чего больше. (хотя ничто не мешает :))

Процесс экспорта. В английском варианте он отлично описан в X2_GFX_Modding.pdf в части 3 - Exporter usage. Здесь же я кратко опишу процесс экспорта. При экспортировании модели появляется окошко, в котором мы можем видеть три кнопки Body, Scene, Combined и три опции Verbose, Binary, Debug Log.

Нажимая на Body, Scene или Combined мы создаём модель соответствующего типа. Опции Verbose, Debug Log использовались разработчиками для отладки, так что для нас они пользы не представляют. Опция Binary позволяет сохранить модель в сжатом виде так что она занимает меньше места и самое главное быстрее грузится, однако наглядность информации внутри файла естественно снижается. При экспортировании модели с помеченной опцией "Binary" вместо .bod (body) файла создаётся .bob(binary body) файл. Единственно что ещё важно знать - при создании наших моделей крайне желательно именовать их начиная с номеров выше 10500, иначе могут возникнуть проблемы использования их в качестве мода.

Рассмотрим идеологию названия моделей.

Body-модели внутри их самих можно называть как угодно, желательно добавлять в начале каждого имени "B_". Например: разместим три шарика и обзовём каждый из них B_sharik1,B_sharik2,B_sharik3, присвоим им цвет, текстуры и т.п. (все экспортируемые свойства описаны в X2_GFX_Modding.pdf - там необходимая инфа для 3D-моделлеров). Для того, чтобы такая модель стала игровой body-моделью, необходимо экспортировать её, и назвать числом (не используя никаких букв), типа 10525,11100, главное чтобы число было больше 10500. Эти числа будут позже использованы в scene-модели. Не забудьте отцентрировать модель как об этом пишут в X2_GFX_Modding.pdf.

Body-модели можно просматривать, и конвертировать в max-формат с помощью программ и скрипта, описанных выше.

Scene-модели устроены как чертёж. Внутри них по сути расположены метки, в позиции которых в игре вставляются body-модели. В принципе как метку мы можем использовать всё что угодно, лишь бы были определены координаты и направление (и ещё возможно вращение), - например кубик :). Хотя удобнее конечно поставить туда ту запчасть, которая там будет реально использоваться (тогда будут видны её направленность и геом. размеры) - но в случае если мы собираем scene-модель в основном из стандартных запчастей из игры, то их МАХ'овских моделей у нас нет, и поэтому приходится вместо них использовать кубики :). Каждая метка имеет своё имя - по нему определяется запчасть, и в некоторых случаях определяются её функциональные параметры. Приведу здесь желательный формат (рекомендуемый разработчиками) для именования меток.

0) для центра модели - имя метки [940(/буквы)] - например 940Mainbody - каждая модель корабля должна иметь такую метку! (виртуальный центр) иначе она не будет экспортирована.

1) для декораций - крыльев/навигационных огней/кабин/двигателей/антенн/... - имя метки должно быть в виде [число(/буквы)] - вместо числа подставляется body-модель. Например 930wing, 930wing02, 931booster, 10318 и т.д

2) для хвостов от двигателей - [число/(_номер)(/буквы)] например 905_1, 770_1bb, 770_1abcd1 и т.д.

3) для выхлопов маневровых движков - [число(/буквы)/_номер] - (это небольшие струйки пара появляющиеся при разворотах корабля) - как получить значение _номера описано на странице 5 X2_GFX_Modding.pdf

4) для кокпитов(кабин изнутри) - [число/_номер(/буквы)] например 928_1cp, 939_2 и т.д. Внимание! Эти _1, _2, _4 и т.д. играют важную роль как идентификаторы кокпитов, дальше объясню почему.

5) для лазеров/турелей - [число/_номер(/буквы)] например 106_1, 106_1b01, 939_4b и т.д. Параметр _номер логически привязывает этот лазер/турель к номеру кокпита. Например у нас есть кокпит турели 939_2, тогда лазеры этой турели будут выглядеть например как 944_2b1, 944_2b01, 944_2b02 и т.п. Смысл: при стрельбе из этого кокпита(основной кабины, или кабины турели) будут стрелять именно эти лазеры расположенные около этой кабины.

Итак, мы разместили все необходимые запчасти в нужных координатах, повернули каждую из них в нужное направление, и теперь осталось лишь экспортировать scene-модель и внести коррективы в файл TShips. Но перед экспортом scene-модели в bod или bob формат экспортируйте её сначала просто в bod формат (без включенной галочки "Binary"), и посмотрите внутри неё (Windows commander тут как раз пригодится) на строчки типа:

P 0; B 940; N 940Mainbody;

P 1; B 885; C 1; N 885_1Cockpit;

P 2; B 106; C 1; N 106_1laser1;

P 3; B 106; C 1; N 106_1laser2;

и т.д.

Видите параметр "P"(Part) в начале каждой строчки? Он будет необходим нам для прописывания некоторых частей в TShips файле так что запишите где-нибудь на листике какой номер к какой части принадлежит. например "106_1laser1 - 2, 106_1laser2 - 3" и т.д.

Если будете использовать в своей модели стандартные запчасти, некоторые из них описаны всё в том же X2_GFX_Modding.pdf, но там описано далеко не всё. Поэтому советую просмотреть bob файлы из папки cut - там можно, хоть и с трудом, прочитать из каких частей составлялись модели кораблей, и эти данные определённо могут быть полезны :).

Ещё не забудьте глянуть в GFX_Modding насчёт упрощенных моделей, используемых при рендеринге на разных дистанциях (но это в общем-то не обязательно :))

Короче, дальше дело только за 3D художниками :)

ЧАСТЬ 2 - файл TShips и формат кораблей в нём.

Файл TShips.pck (реально TShips.txt в распакованном варианте) лежит в папке types.

В самом начале файла есть строка из двух цифр - это версия файла (изменится если изменится формат описания кораблей) и количество строк в файле. Каждый корабль в этом файле описан одной строкой (довольно длинной :)), в конце каждой строки находится строковый идентификатор корабля (который похоже ни на что не влияет.

Добавление кораблей

Внимание! благодаря Пилоту CheckerTwo получена сл. информация:

"Маленькое уточнение.

В редакторе скриптов можно криэйтить следующие шипы,

прописанные в tships по номерам (начиная с 0 - SS_SH_A_TL):

0-8, 10-43, 49-50, 52, 61-95, 99-100, 103-107.

Всего 86 кораблей. Все остальные как бы недоступны.

Т.е. в редакторе скриптов они отсутствуют для выбора.

В список "недоступных" попадают:

SS_SH_X_M0;

SS_SH_X_TS_P,SS_SH_S_TS_P,SS_SH_P_TS_P,SS_SH_B_TS_P,SS_SH_T_TS_P;

SS_SH_ROBOT;

SS_SH_LOGBOOK;

SS_SH_E_TS,SS_SH_E_M1,SS_SH_E_DRONE,SS_SH_E_SPACESHUTTLE,SS_SH_E_CARRIER;

SS_SH_GATE,SS_SH_M0_GUN,SS_SH_PULLER,SS_SH_R1,SS_SH_R2;

SS_SH_APGUNNER;

SS_SH_COMET;

SS_SH_TAXI,SS_SH_MOD_TL,SS_SH_DUMMY;

SS_SH_K_M0;

SS_SH_K_M0GEN;

SS_SH_REPAIRDRONE;

Убил бы разработчиков

Из этих 86 игра не использует 11, в их описании значение 3dbody = -1, но их можно создавать и вообще это то что нужно для моддинга!:

SS_SH_A_M3;
SS_SH_A_TSA;
SS_SH_B_M3;
SS_SH_B_M4;
SS_SH_S_TS;
SS_SH_S_M5;
SS_SH_T_M4;
SS_SH_T_M5;
SS_SH_P_M3_2;
SS_SH_P_M4;
SS_SH_P_M5A;

Нужно заметить, что номер строки корабля в tships однозначно соответствует подтипу корабля (параметр s) в xml описания объектов галактики. (Спасибо Dimaxx за редактор карт и хелп к нему.)

Например, пиратский шип

<o id="0" t="7" x="0" y="0" z="0" s="43" r="0">

соответствует описанию 43 корабля в tships (SS_SH_A_TS_P).

В редакторе скриптов при присвоении значения типа корабля
переменной генерится такой код,
<sval type="array" size="7">
<sval type="int" val="104"/>
<sval type="int" val="0"/>
<sval type="int" val="1"/>
<sval type="int" val="9"/>
<sval type="int" val="458795"/>
<sval type="int" val="1"/>
<sval type="int" val="-1"/>
</sval>
где 458795 = $0007002B и младшее слово опять же
соответствует номеру корабля.

Что из этого всего следует? Скорее всего все прошито в exe
намертво. В конфигах можно менять только кое-какие свойства.
Да, это не фрилансер.

PS: С АП-Ганером что-то непонятно. А мне казалось что я его того,
создавал-летал. Может эгософты в 1.3 поменяли чего? Проверьте, pls.
Че не так."
CheckerTwo©

Т.к. файл TShips наполовину заполнен "мусором", то простой способ как найти нужный корабль - просмотрите bob файлы из папки cut - там в начале есть текстовая строка в которой содержится намёк на корабль, например "SRC: F:\SRC\3DSMAX-Work\X2_The-Threat\Scenen-Ships\revised\4098_Par_M1-Carrier_new.max" - Паранидский М1. Так ищем до тех пор пока не найдём то что нам нужно, и когда находим записываем номер .bob файла и ищем по этому номеру строку в TShips.

Правда есть способ гораздо проще - запустить X2 Object Modder - и там просто пролистать в списке кораблей, найти нужный нам и посмотреть какой у него идентификатор :).

Формат строки описания корабля
На английском частично описан в X2_GFX_Modding.pdf. Для примера разберём здесь корабль Teladi Osprey - идентификатор SS_SH_T_M6.

940;0;0.04500;0.04500;0.09999;11;4511;19000;3450;101;1;4;217;1000;
112;247;4167;4508;2020;6;3;3;4;9;10;10;500;1500;61;5;61;6;60;2;0;0;
0;0;0;0;-1;4;5;45000;40;41;3;4;1;0;928;3;2;1;939;9;3;2;939;10;4;3;
939;14;4;1;2;1;2;1;1;887;1;-1;-1;2;1;887;2;-1;-1;3;1;2;1;3;1;944;
11;-1;-1;4;1;3;1;4;1;944;12;-1;-1;5;2;4;2;5;1;944;15;-1;-1;6;1;944;16;-1;
-1;1;100000;25;1;0;SS_SH_T_M6;

из .bob файла под номером 04167 выписал названия:
887_1b - это пушка
887_1bb - ещё одна пушка
928_1co - кокпит
906b - закорючка радара
930wing - крылья
931boost - движок
931boost01 - второй движок
940mainbody - виртуальный центр модели корабля
939_2b - кокпит
939_3b - кокпит
944_2b - пушка турели
944_3b - пушка турели
53docking - место стыковки
939_4b - кокпит
944_4b - пушка турели
944_4b01 - пушка турели
905_b - выхлоп от двигателя
905_b01 - выхлоп от второго двигателя
(дальше идут навигационные огоньки 10ххх и десяток выхлопов маневровых движков)

Для удобства описания разобью строку на части:
940; - номер центрального тела (body) для объекта (если там что-то отличное от 940 значит это не корабль (в обычном смысле этого слова))

0; - body, используемое для показа объекта в различных меню (там всегда 0, т.е. то же самое что и в космосе)

0.04500;0.04500;0.09999; - скорости поворота по осям - определяют маневренность

11; - тип корабля - 0-TL 1-TS 2-M0 3-M1 4-M2 5-M3 6-M4 7-M5 8-TL_P 9-TS_P 10-G0 11-M6 12-TP.

4511; - номер в xml-файле со всем текстом игры, по которому прописано инфо о корабле. номер+1 = длинное описание к кораблю.

19000; - скорость в юнитах в сек.

3450; - ускорение в юнитах в сек.

101; - как звучит двигатель в движении

1; - средняя задержка реактора(реакции) (?) (всегда равно 1)

4; - как выглядит выхлоп от двигателей

217; - как светится огонёк двигателя (скорее всего, не уверен полностью)

1000; - количество энергии (мощность реактора МегаВатт), регенерируемое в секунду

112; - минимальная громкость звуков издаваемых кораблём

247; - максимальная громкость звуков издаваемых кораблём на максимальной скорости

4167; - номер .bod или .bob файла, представляющего из себя scene-модель корабля

4508; - номер .bod или .bob файла, представляющего из себя внутренний вид главной кабины корабля

2020; - бит-маска, определяющая какие пушки можно поставить на корабль (расшифровку см. ниже)

6; - макс. количество лазеров устанавливаемых на корабль (в нашем случае 2 пушки +1+1+2 турели = 6)

3; - максимально возможный тип щита (0 один мегаватт, 1 пять мегаватт, 2 двадцать пять мегаватт, 3 сто двадцать пять мегаватт)

3; - максимально возможное количество щитов

4; - максимально возможный тип ракет (-1 нет, 0 mosquito, 1 wasp, 2 dragonfly, 3 silkworm, 4 hornet. p.s. не забывайте что ракеты класса М например не влезут ни в один М5 :))

9; - это число показывает, скока ракет будет в трюме в стандартной поставке при заказе корабля для НПЦ. Для игрока не имеет смысла - thanks to Dimaxx

10; - количество возможных апгрэйдов скорости (1 штука = 10% прибавки)

10; - количество возможных апгрэйдов маневренности (1 штука = 10% прибавки)

500; - стартовая вместимость трюма

1500; - максимальная вместимость трюма (1500-500=1000=кол-во возможных апгрейдов трюма)

61; - тип для дополнительного кокпита 1 (номер строки в файле TCockpits, описывающий макс. возможное оружие. Помните, что строки нумеруются с 0 (не считая первой 13;103;, она как бы под номером -1), так что если тут написано 61, то строка эта будет

62 (если начинать считать строки с 1))

5; - текст. ID для доп. кокпита 1 (0 главный кокпит, 1 передний, 2 задний, 3 левый, 4 правый, 5 верхний, 6 нижний)

61; - тип для доп. кокпита 2

6; - текст. ID для доп. кокпита 2

60; - тип для доп. кокпита 3

2; - текст. ID для доп. кокпита 3

0; - тип для доп. кокпита 4

0; - текст. ID для доп. кокпита 4

0; - тип для доп. кокпита 5

0; - текст. ID для доп. кокпита 5

0; - тип для доп. кокпита 6

0; - текст. ID для доп. кокпита 6

-1; - количество кораблей которые могут стыковатся к этому (минус перед числом означает что стыковка внешняя, т.е. снаружи корабля)

4; - макс. тип груза который вмещает корабль

5; - раса, обычно использующая этот корабль

45000; - количество(крепость) единиц хулла(корпуса)

40; - эффект взрыва корабля (разваливание на части)

41; - эффект взрыва деталек корабля (после разваливания на части)

3; - тип хвоста выхлопа от двигателя

...

после этого параметра идут характеристики вооружения корабля, опишу их подробно.

4; - количество кокпитов (основной кокпит + кокпиты турелей)

1;0;928;3; (для каждого кокпита)

2;1;939;9; (для каждого кокпита)

3;2;939;10; (для каждого кокпита)

4;3;939;14; (для каждого кокпита)

4; - количество турелей (пушки основного кокпита, верхнего, нижнего, заднего кокпитов)

1;2;1;2; (для каждой турели)

* * 1;1;887;1;-1;-1; (для каждого лазера)

* * 2;1;887;2;-1;-1; (для каждого лазера)

3;1;2;1; (для каждой турели)

* * 3;1;944;11;-1;-1; (для каждого лазера)

4;1;3;1; (для каждой турели)

* * 4;1;944;12;-1;-1; (для каждого лазера)

5;2;4;2; (для каждой турели)

* * 5;1;944;15;-1;-1; (для каждого лазера)

* * 6;1;944;16;-1;-1; (для каждого лазера)

Теперь распишу какой параметр за что отвечает

Для каждого кокпита:

1) номер кокпита, прописанный в scene-модели (928_1co, 939_2b, 939_3b, 939_4b)

2) расположение турели (просто перечисление от 0 до ...)

3) модель кокпита (928_1co, 939_2b, 939_3b, 939_4b)

4) номер "P"(Part) прописанный в scene-файле (вы не забыли их записать? :) что-нибудь типа P 10; B xxx; C x; N xxxxxx (если смотреть файл в binary формате, то можно лишь только догадыватся какой номер имеет запчасть... но нам всегда нужна эта информация только из наших собственных .bod файлов, так что это не страшно))

Для каждой турели:

1) порядковый номер первого лазера в турели (минимум 1 максимум 18, важен порядок т.к. это будет отображатся в меню оружия корабля, см. ниже параметр №1 для каждого лазера)

2) количество лазеров в пушке (6 пушек, каждая из них одинарная, поэтому количество лазеров совпадает с кол-вом турелей в параметре №4)

3) какой кокпит контроллирует эти пушки (944_4b, 944_4b01, 887_1b, 887_1bb, 944_3b, 944_2b)

4) количество пушек в турели (у нас 4 турели, в них 2 пушки спереди, 1 вверху, 1 внизу, 2 сзади)

Для каждого лазера:

1) порядковый номер пушки (от 1 до 18)

2) лазеры в пушке (всегда 1. Т.е. даже например лазеры в двойной пушке 107 будут описыватся к примеру так: 1;1;107;1;(111;1;) ** 2;1;107;1;(375;2;))

3) номер модели лазера (944_4b, 944_4b01, 887_1b, 887_1bb, 944_3b, 944_2b)

4) номер "P"(Part) прописанный в scene-файле к (что-нибудь типа P 11; B 944 N 944_2b, или P 16; B 887; C 2; N 887_6xyz и т.п.)

5) модель ствола пушки - если пушка "дёргается" при выстреле, то для одинарной (к примеру модель 106) тут 111, для двойной (к примеру модель 107) 375, иначе -1

6) путь к модели ствола пушки - если пушка "дёргается" при выстреле, то одинарной тут 1, для двойной (модель 107) 2, иначе -1

... после описания пушек идут ещё несколько параметров (были бы важны если бы корабль был как товар на станции)

1; - вес единицы товара(корабля)

100000; - коэффициент (коэффициент * некую константу стоимости = цена корабля)

25; - вариация цены, если товар - первичный ресурс

1; - вариация цены, если товар - вторичный ресурс

0; - класс груза (как товара)

SS_SH_T_M6; - текстовый идентификатор корабля (менять его бесполезно).

возможные типы устанавливаемых пушек для кокпитов

Простой спобоб зашифровки –

1,2,4, - 1) GIRE A, 2)GIRE B, 3)GIRE G

8,16,32, - 4)PAC A, 5)PAC B, 6)PAC G

64,128,256, - 7)HEPT A, 8)HEPT B, 9)HEPT G

512,1024,2048, - 10)PSG A, 11)PSG B, 12)PSG G

4096,8192,16384, - 13)Mining, 14)Kyon A, 15)Kyon B

32768,65536,131072, - 16)Kyon G, 17)MassDriver, 18)Ion Disruptor

262144,524288,1048576, - 19)PPC A, 20)PPC B, 21)PPC G

2097152,4194304,8388608 - 22)OrbitalLaser, 23)Khaak_Endfight, 24)Repair

То, какие пушки держит кокпит, определяется суммой вот этих вот чисел. (1, 2, 2*2, 2*2*2...)

Например AGIRE, BGIRE, APAC, BPAC, AHEPT, BHEPT, GHEPT, ID = 1+2+8+16+64+128+256+131072.

Простой способ расшифровки –

например так: берём бит-маску (в нашем случае "2020")

1) запускаем калькулятор (пуск->программы->стандартные->калькулятор :)), щёлкаем на опции вид->инженерный, далее пишем цифры 2020 и жмём на опцию bin(binary) (это или в меню "вид", или там где опции hex-шестнадцатиричная, dec-десятичная, oct-восьмиричная системы счисления)

2) полученное число (из "2020" получаем "11111100100") разделяем на группы после каждого третьего знака, начиная с конца, к примеру точками .11.111.100.100

3) пишем части полученной строки в обратном порядке - 100.100.111.11

4) если в последней части не хватает второго или третьего знаков, добавляем недостающие нули в начало .11-.011

5) инвертируем числа в полученных группах 100.100.111.011 - 001.001.111.110

6) теперь видно (посмотрите на таблицу выше), что можно поставить в этот кокпит –

3:GIRE G, 6:PAC G, 7:HEPT A, 8:HEPT B, 9:HEPT G, 10:PSG A, 11:PSG B.

Вот ещё пример: возьмём например телади-М5, бит-маска = "15".

1) 15-1111

2) 1.111

3) 111.1

4) 111.001

5) 111.100 - 1:GIRE A, 2:GIRE B, 3:GIRE G, 4:PAC A.

или из девятого параметра строки 62(61 по программистски :)) файла TCockpits: 438->110110110->110.110.110->011.011.011 - это в точности пушки верхней и нижней турелей Оспрея.
(короче принцип думаю понятен, способ расшифровки можете свой придумать, такой какой вам будет удобнее использовать :))

(кстати, под кораблями может подразумеваться всё - и то что летает, и то что не летает, всё - станции, корабли, космомухи :), всякие там ворота, навигационные буи... фактически кораблями являются даже заряды плазмы выпущенные из пушек :) (хотя они описываются в другом файле и немного не так) но это уже другая история ;))


Вступление о моддинге

О моддинге.

Д ля того чтобы эффективно работать со скриптами в Х2 необходимо знать как устроена Х2-Вселенная и находящиеся в ней объекты. В связи с этим начинаю выкладывать информацию о моддинге которая обязательно вам понадобится, если вы заходите сделать свой мод, внести что-то новое во Вселенную Х. И хочу выразить благодарность на страницах этого проекта, всем пилотам проводящим кучу времени разбирая горы цифр, собирающих крупицы информации изучая устройство этой, такой любимой нами вселенной.