Информация: Уважаемые посетители! В течение нескольких месяцев на форуме существовала проблема с регистрацией новых пользователей, о которой администрации стало известно недавно. Если вы ранее пытались зарегистрироваться на форуме, но не получили на ваш e-mail письмо с ссылкой для подтверждения регистрации, просим вас зарегистрироваться повторно. Приносим извинения за доставленные неудобства. Если вы все еще испытываете проблемы с регистрацией на форуме, обратитесь за помощью на e-mail: mr.angelo@railroadsim.net

Язык скриптования Auran Game Script

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

Язык скриптования Auran Game Script

Сообщение TRam_ » 18.01.2009, 14:16

итак (потом всё это прийдётся собирать в "русский перевод АПИ")

1) скрипт состоит из классов, которые в свою очередь содержат методы и глобальные переменные

2) классы могут наследоваться, т.е. все методы класса - родителя наследуются классом наследником (если не добавлена "перегрузка метода")

например

class MyClass001//обьявляем класс-родитель
{
}

class childMyClass001 isclass MyClass001//обьявляем класс-наследник
{
}

Итак, у этих классов есть глобальные переменные и методы
глобыльные переменные (и переменные вообще) бывают 2 видов

1) обычные переменные, такие как
string aaaaa; int n1; bool r; GameObject Mytown;
2) массивы, такие как
int[] massiv1; MapObject[] objectsPack;
и т.д.
Естественно классы, такие как MapObject или GameObject должны быть определены хотя бы в одном из классов, которые
а) содержатся в одном из скриптов, находящемся в папке Scripts директории трейнз
б) эти классы содержится в данном скрипте
в) эти классы находятся в другом скрипте, который "подключили" к этому

(напомню, подключение скрипта из папки локомотива происходит при вставке в директорию куида копии необходимого Вам скрипта и постановке в начало скрипта строки

include "****.gs"

где ****.gs - подключаемый скрипт. Не правда-ли напоминает подключение библиотек СИ ?) (в 2009 можно подключать скрипты не только из директории куида, но и из внутр. папок, но для этого надо с конфигом возиться)

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

В принципе, при описании потоки и функции друг от друга почти не отличаются, но выполняют 2 совершенно разные функции

1) функция - является самым обычным "линейным алгоритмом", который подробно изучают школьники. Вызывающая его процедура ждёт, пока он закончится, поэтому если Вы поставите в нём бесконечный цикл, то убедитесь, что трейнз как и МС-ДОС тоже может "виснуть". Применяются, если не охота писать один и тот же кусок кода, либо для того, чтобы проще было изменять "кусками" функции обьекта-родителя, пользуясь методом "перегрузки". Напирмер,


class Myclass
{

float ploschad_pramougolnika(int a; float b)//функция с 2 переменными
{
float c=a*b; //вычисляем площадь
return c; //выводим значение площади
/*хотя можно было не объявлять переменную с, а просто записать

return a*b;
*/
};
и пример функции - вызывающей эту

int getploschad2(float a; int b)//данная функция должна "отбрасывать" дробную часть числа а, и передать его 1 функции именно 1 аргументом(ну я допустим так захотел)
// напомню, что локальные переменные, обьявленные в разных функциях абсолютно не взаимодействуют, не смотря на то, что они имеют одинаковые названия
{
int с = (int)a; // итак, у нас есть преобразованный в челосисленный агрумент а
return ploschad_pramougolnika(c,b); //напомню, преобразование из целого в дробное идёт автоматически
};
};// не забываем, что у нас класс тоже закончился


2)поток. Это почти тоже что и функция, НО при его загрузке вызывающая процедура "забывает" о нём и продолжает работать как ни в чём не бывало. Т.е. мы получили 2 одновременно работающих процесса - вызывавшая процедура и существующий поток (похоже на использование конструкции с функцией fork() из API linux). Распределение времени процессора между ними происходит автоматически (в отличии от КРС).
пример чуть другой

class MyClass2
{

int a1=0;

thread void Checker(float dt1; int newNumber) //итак перед Вами поток. Как видите, схема описания отличается от функции только наличием ключевого слова thread. Я хочу написать поток, который всю игру будет РОВНО раз в промежуток времени dt1 проверял значение переменной a1, и если a1 была равна 0, то заменял её значение на newNumber.Учтите, что поток вообще не может возвращать значение функции(она продолжила выполняться) поэтому он должен быть обязательно void
{
while(/*думаю, здесь как раз самое место поговорить о логическом типе bool в трейнз. Аурановцы постарались сделать его как java и им подобным, т.е. с сохранением Си шного синтаксиса "если число не равно нулю, то это "да", если равно, то "нет""
т.е. если Вы хотите записать ddd1= "нет" (присваивание здесь СИшное, отличается от "паскалевского"), то можете написать ddd1=false; или ddd1=0;
если же наоборот, ddd1= "да", то можете написать сколько угодно вариантов, например ddd1=true; ddd1=10; ddd1=-0.0000001221122; ddd1=22e+1; и так далее. для экономии места обычно пишут ddd1=1;, хотя более "читаемая" запись ddd1=true;
Кстати, об операторе "сравнения". Он тут полностью Сишный, т.е. a==b - или "да", или "нет", но в отличие от СИ логические операторы || и && заменены паскалевскими or и and.
ну а здесь для краткости мы впишем 1, т.к. наш скрипт будет работать всю игру*/ 1)
{

if(a1==0 /*можно было бы записать if(!a1) - это эквивалентно */)
{
a1=newNumber;
}

Sleep(dt1); // а это как раз та функция, которая озволяет просто писать многопоточность. Ведь пока этот поток работает, он требует ресурсы, так же как и функция, но когда он "спит", то эти ресурсы передаются остальным потокам, а также графическому движку игры и прочему. Поэтому если Вы протестируете этот скрипт на ОООЧЕНЬ доисторическом компе, то разница в производительности игры при включении потока при dt1=0.001 будет знаительной по сравнению с dt1=10 (т.е. проверять раз в секунду)
}

}

//ну и процедура, вызывающая этот поток
void init0(void) //слово void говорит, что функция не выводит (в функцию не вводят) никаких переменных
{

Checker(0.01,40);

}


Публичная функция может выглядеть так

class Myclass3
{

public float ploschad(int a; float b) // публичная функция
{
return a*b;
};

public thread void ploschad2(int a; float b) // публичный поток
{
Sleep(1);// ждём 1 сек, а потом выводим
return a*b;
};
}


а класс 4 их использует

class Myclass4
{


Myclass3 ObjClass3;

int da(void)
{
float square = ObjClass3.ploschad(2,3.4444);

}

}

А теперь мы хотм сделать "наследника" класса Myclass3, который должен вычислять плошадь прямоугольника, если b - целое, и если b -дробное, то вычислял площадь треугольника (ну задание такое поставили)

class MyChildclass isclass Myclass3
{

public float ploschad(int a; float b) // публичная функция, которую мы хотим перегрузать
{

if(b==(int)b)
{

inherted(a,b); //вот это и есть "перегрузка" метода. Т.е. вызывается функция объкта-родителя, которой передаются аргументы. Естественно, результат ploschad класса Myclass3 будет возвращаться функции ploschad класса MyСhildclass, которая выдаст его без каких-либо изменениий
}
else return a*b/2; //площадь треугольника
};

}
Кстати, функция public thread float ploschad2 останется без изменений в обьекте-наследнике. Если же мы напишем её новую декларацию, старая (объекта-родителя) использоваться уже не будет

Класс может быть наследником одновременно 2 классов

class MyChildclass2 isclass Myclass3,Myclass4

Если же мы используем метод этого класса в одной из функций(потоков) этого же класса, то правильно будет написать например

int z= me.ploschad(2,1);

но в то же время можно чуть упростить запись, опустив me :

int z=ploschad(2,1);


И последнее - классы можно "преобразовывать". К сожалению, трейнз не всегда может правильно "собрать" это дерево родителей-наследников и не может для наследника всегда вызвать функцию родителя, или наоборот, требуется вызвать именно функцию обьекта-родителя. Тогда нам потребуется оператор преобразования классов. Допустим, нам надо преобразовать объект me134 класса MyChildclass2 в класс Myclass3

MyChildclass2 me134;

Myclass3 newclass9;

newclass9= cast<Myclass3> me134; // теперь мы получили объект me134 преобразованный к классу-родителю Myclass3

предпоследнее. Как известно, массивы, такие как int[] massiv1; необходимо создавать, то есть выделять память для переменных, войдущих в их состав. Для этого используется специальное ключевое слово new . Вообще это некий аналог СИшного alloc'a, но вручную считать, сколько массиву потребутся памяти не надо - движок это сделает за вас ! Инициализировать этот массив можно статически

massiv1=new int[30];

или динамически

void SetMassiveSize(int number)
{
massiv1=new int[number];
}

Если же вам требуется создать единственный элемент, то можно сделать так

newclass9=new Myclass3();

но учтите. Полученный таким образом элемент (не являющиййся стандартным типом как int float sting bool) обязательно инициализировать, т.е. он должен содержать явно написанную функцию public void Init(void) и прежде чем этим объектом пользоваться, надо эту функцию вызвать. Пример примерно такой


class Class01
{
public int a;
public void Init(void)
{
a=0;
}

};


class UsingClass01
{
Class01 myobj1;


public void using(int q)
{
myobj1=new Class01();
myobj1.Init();
myobj1.a=701;
}
}

И ещё 2 полезные фунукции.
1) функция int size() . Определяет число элементов массива. Учитывая, что нумерация массивов в trainz начинается с 0, последний элемент массива (size() -1)
пример

int i;
for(i=0; i<=massiv1.size()-1;i++)
{
massiv1[i]=0;
}

2) функция bool isclass( class) . Определяет, принадлежит ли данный объект классу. Аргументом является класс (не элемент класса !) принадлежность к которому проверяют. Полезна, если объект был про cast ован в объект класса-родителя. Полезна, например, для различения локомотивов и нескриптованных вагонов
Пример составлен для скрипта вагона

#include "Locomotive.gs"
#include "Train.gs"


class myVehicle isclass Vehicle
{
int lastLocoNumber=-1;

void int getlastLoco(void)
{
Train train1=me.GetMyTrain();
Vehicle[] veh_array=train1.GetVehicles(); // как видите, функция возвращает уже готовый инициализированный массив
int i=veh_array.size()-1;

while(i>=0 and lastLocoNumber==-1)
{
if(veh_array.isclass(Locomotive))
{
lastLocoNumber=i;
}
i--;
}

return lastLocoNumber;
}


}
Последний раз редактировалось TRam_ 09.09.2009, 19:57, всего редактировалось 2 раз(а).
в z7 всё можно, а что нельзя - можно в sU
Аватара пользователя
TRam_
 
Сообщения: 1905
Зарегистрирован: 30.11.2007, 20:14
Благодарил (а): 2 раз.
Поблагодарили: 63 раз.
Играю в: Auran Trainz
Роль: Разработчик
Имя: Владимир

Re: Язык скриптования trainz game script

Сообщение TRam_ » 18.01.2009, 14:28

и небольшое дополнение - функции, помеченные словом native (там же где и public) написаны в библиотеках игры, и являются частью движка. Их изменить нельзя (они написаны на си-коде и скопилированы в библиотеки .gsl ), хотя "перегружать" - пожалуйста.
в z7 всё можно, а что нельзя - можно в sU
Аватара пользователя
TRam_
 
Сообщения: 1905
Зарегистрирован: 30.11.2007, 20:14
Благодарил (а): 2 раз.
Поблагодарили: 63 раз.
Играю в: Auran Trainz
Роль: Разработчик
Имя: Владимир

Re: Язык скриптования Auran Game Script

Сообщение babai » 20.01.2009, 00:12

Ну точно как в С++. А есть ли где то описание всех функций которые можно использовать в скриптовании?
Аватара пользователя
babai
 
Сообщения: 29
Зарегистрирован: 02.01.2006, 22:05
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Играю в: Auran Trainz

Re: Язык скриптования Auran Game Script

Сообщение agmike » 20.01.2009, 14:51

апи на files.auram.com, файлы скриптов в папке scripts
The Cake is a Lie.
agmike
 
Сообщения: 1025
Зарегистрирован: 26.08.2006, 12:43
Благодарил (а): 0 раз.
Поблагодарили: 3 раз.
Играю в: Пульт ДНЦ

Re: Язык скриптования Auran Game Script

Сообщение babai » 20.01.2009, 16:17

Благодарю!
Аватара пользователя
babai
 
Сообщения: 29
Зарегистрирован: 02.01.2006, 22:05
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Играю в: Auran Trainz

Re: Язык скриптования Auran Game Script

Сообщение TRam_ » 04.03.2009, 21:09

кстати, очень важное дополнение.

Класс в трейнз должен быть УНИКАЛЬНЫМ ! иначевозникнет ошибка! поэтому если Вы переделываете чужой скрипт, не забывайте изменять class на свой (и в скрипте, и в конфиге)
в z7 всё можно, а что нельзя - можно в sU
Аватара пользователя
TRam_
 
Сообщения: 1905
Зарегистрирован: 30.11.2007, 20:14
Благодарил (а): 2 раз.
Поблагодарили: 63 раз.
Играю в: Auran Trainz
Роль: Разработчик
Имя: Владимир

Re: Язык скриптования Auran Game Script

Сообщение agmike » 04.03.2009, 22:07

ID библиотеки состоит из CRC32 содержимого плюс CRC32 имени файла, так что это надо очень постараться для получения таких проблем
The Cake is a Lie.
agmike
 
Сообщения: 1025
Зарегистрирован: 26.08.2006, 12:43
Благодарил (а): 0 раз.
Поблагодарили: 3 раз.
Играю в: Пульт ДНЦ

Re: Язык скриптования Auran Game Script

Сообщение logoff » 06.03.2009, 13:03

Прошу прощения за оффтоп, есть ли мануалы на английском или русском по скриптованию или советы какие-нибудь. Я в скриптах нихрена не понимаю, нужны источники народной мудрости.
logoff
 
Сообщения: 422
Зарегистрирован: 11.02.2009, 15:05
Откуда: Санкт-Петербург
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
Блог: Просмотр блога (1)
Играю в: Auran Trainz
Роль: Пассажир :)
Имя: Михаил

Re: Язык скриптования Auran Game Script

Сообщение agmike » 06.03.2009, 13:10

Начинать нужно с простых книжек по программированию
The Cake is a Lie.
agmike
 
Сообщения: 1025
Зарегистрирован: 26.08.2006, 12:43
Благодарил (а): 0 раз.
Поблагодарили: 3 раз.
Играю в: Пульт ДНЦ

Re: Язык скриптования Auran Game Script

Сообщение VladeK » 06.03.2009, 19:28

agmike, согласен.
только когда нам начали читать классы в С++, я стал
больше понимать выдержки из треинзовских скриптов :)
Электромеханик! Помни! Закорачивание, переворачивание и подпитка реле - тягчяйшее преступление перед государством.
Аватара пользователя
VladeK
 
Сообщения: 131
Зарегистрирован: 24.06.2007, 16:49
Откуда: Киев
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
Имя: Владислав

Re: Язык скриптования Auran Game Script

Сообщение TRam_ » 05.09.2009, 17:19

раз уж прикрепили тему,
ссылка на статью о сообщениях http://www.trainsim.ru/forum/showpost.p ... ostcount=1
ссылка на статью о обработке клавиш http://www.trainsim.ru/forum/showpost.p ... stcount=22

Файлы с объявлением и описанием ВСЕХ скриптовых функций API (Вашей версии trainz) лежат в её папке Scripts (рекомендую начинать изучение со скриптов Vehicle.gs (вагон) , JunctionBase.gs , Train.gs и World.gs)

для того, чтобы не рыться в поисках описания какой-то функции, можно скачать c http://files.auran.com/TRS2006/manuals/ файл TRS2006-API.zip (это файл-справка, там можно делать поиск).

При нажатии edit script открывается самый обычный блокнот. Да и вообще я только блокнотом и пользуюсь при редактировании скриптов(открыть с помощью -> блокнот). Единственное что - нельзя нажимать "сохранить как" - при этом теряется кодировка, а какую ставить я не знаю. При "сохранить" скрипт обязан работать...

А в ошибке всё указано (если 2006-классик) в т.ч. строка файла, где она найдена, либо надо открывать jetlog.txt (если 2009) и там смотреть описание

Если Ваш скрипт выбивает 2009 без сохранения информации в jetlog.txt (такое иногда бывает при работе с кабинами),
советую попробовать его отладить в более ранней версии trainz

pharse error - не хватает скобок/в коде символы не той кодировки
ER NULLRefference - вызов функции/элемента неинициализированного объекта
ER NULLArray (?) - работа с элементом, номер которого больше длинны массива
Последний раз редактировалось TRam_ 09.09.2009, 21:59, всего редактировалось 1 раз.
в z7 всё можно, а что нельзя - можно в sU
Аватара пользователя
TRam_
 
Сообщения: 1905
Зарегистрирован: 30.11.2007, 20:14
Благодарил (а): 2 раз.
Поблагодарили: 63 раз.
Играю в: Auran Trainz
Роль: Разработчик
Имя: Владимир

Re: Язык скриптования Auran Game Script

Сообщение AlexanderG » 06.09.2009, 00:13

Единственное что - нельзя нажимать "сохранить как" - при этом теряется кодировка, а какую ставить я не знаю.
Просто не надо кириллицу использовать в коде, для этого есть string tables.
http://files.auran.com/TRS2006/manuals/ файл TRS2006-API.zip (это файл-справка, там можно делать поиск).
Давно пользуюсь, безумно удобная вещь. А для 09 нету?
phace error
Ошибка фазы, да? Parse error -- ошибка в синтаксисе. Я для их отлова использую компилятор GSC.EXE.
Join Dropbox and SHARE YOUR SHIT FOR FREE!
AlexanderG
 
Сообщения: 762
Зарегистрирован: 27.06.2009, 16:54
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
Блог: Просмотр блога (2)
Имя: Александр

Re: Язык скриптования Auran Game Script

Сообщение TRam_ » 06.09.2009, 01:08

Просто не надо кириллицу использовать в коде, для этого есть string tables.
смотри LLC . Там кириллица вписана самым настоящим образом в код "начала браузера", правда в странной кодировке.

А проблема со сменой кодировки у меня была, хотя там кириллицы не было вообще. Так что лучше перестраховываться
Ошибка фазы, да?
отсутствие словаря
в z7 всё можно, а что нельзя - можно в sU
Аватара пользователя
TRam_
 
Сообщения: 1905
Зарегистрирован: 30.11.2007, 20:14
Благодарил (а): 2 раз.
Поблагодарили: 63 раз.
Играю в: Auran Trainz
Роль: Разработчик
Имя: Владимир

Re: Язык скриптования Auran Game Script

Сообщение AlexanderG » 06.09.2009, 11:41

правда в странной кодировке.
Не знаю ни одной "странной" кириллической кодировки :) WIN-1251, KOI8-R, ОЕМ -- выбирай.

отсутствие словаря
Хроническое. Пора бы купить.
Join Dropbox and SHARE YOUR SHIT FOR FREE!
AlexanderG
 
Сообщения: 762
Зарегистрирован: 27.06.2009, 16:54
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
Блог: Просмотр блога (2)
Имя: Александр

Re: Язык скриптования Auran Game Script

Сообщение Dandi » 06.09.2009, 14:44

TRam_ писал(а):"если число равно нулю, то это "да", если не равно, то "нет""
Ашипка вкралась ;)
В этом вашем интернете хрен поймешь, кто прикалывается, а кто реально дебил.
Dandi
 
Сообщения: 100
Зарегистрирован: 05.05.2009, 11:12
Откуда: Волгоград
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Играю в: Auran Trainz
Имя: Александр

След.

Вернуться в [TZ] Другие вопросы

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2