Elite Games - Свобода среди звезд!

X2 - Скрипты - ScE - Примеры скриптов

ПРИМЕРЫ СКРИПТОВ

Ниже будет рассмотрен пример, демонстрирующий стандартную команду «Взять товар по наилучшей цене». Он состоит из нескольких отдельных, логически завершенных скриптов. Почему именно из нескольких? Почему не одним? Ответ на этот вопрос очень прост: как я уже писал в «вступлении», все скрипты будут строится из отдельных кусков – примитивов, например, скрипт !move.movetostation вполне можно использовать и в других скриптах, например, хотя бы «Продать товар по наилучшей цене», а постоянно повторять одни и те же одинаковые куски кода – напрасный расход памяти, гораздо логичнее разбить НС на стандартизированные кусочки кода (примитивы) и далее вызывать их из других НС.

!init.ship.globalscriptmap.pl
Версия: 1
Для версии ScE: 11
Описание: Инициализация всех кораблей расы «игрок»
Аргументы:
Исходный текст:
...
009 global ship map: set: key=COMMAND_GET_WARE_BEST, class=Ship, race=$race, script= '!ship.cmd.getwarebest.pl', prio=0
...

Как мы видим из названия этого скрипта – он является системным (в начале имени стоит знак «!») и не подлежит модификации игроком. Этот скрипт вызывается одним из первых (сразу после запуска игры, когда все данные о галактических объектах уже подготовлены) и занимается присвоением скриптов всем командам и сигналам всех объектов расы «игрок». Я не стал приводить его в этом примере целиком – в данном случае нас интересует лишь строка под номером 009, в которой за командой COMMAND_GET_WARE_BEST всех объектов класса корабль, расы заданной переменной $race, закрепляется НС под названием !ship.cmd.getwarebest.pl и устанавливается для него нулевой приоритет.

!ship.cmd.getwarebest.pl
Версия: 1
Для версии ScE: 11
Описание: Команда корабля игрока «Взять товар по лучшей цене»
Аргументы:
1: ware, Var/Homebase and Resource, 'ware'
Исходный текст:

001 @ =[THIS] ->call script '!ship.cmd.getwarebest.std': ware = $ware

Очень длинный скрипт, он всего-лишь «переводит стрелки» на «стандартный» НС используемый кораблями НПЦ. Здесь [THIS] это ссылка на конкретный экземпляр объекта класса корабль, который только что получил от игрока команду COMMAND_GET_WARE_BEST, и занялся её исполнением. Скрипт имеет один аргумент – тип ресурсов, который нужно найти (его мы указываем при подаче команды кораблю) и передает его скрипту !ship.cmd.getwarebest.std, который также имеет аргумент того же типа. Символ «@» означает, что выполнение скрипта может быть прервано (например, сигналом «SIGNAL_ATTACKED» или любой другой командой/сигналом с таким же или более высоким приоритетом). Результат исполнения скрипта (значение возвращаемое return) в данном случае не анализируется (пустой оператор присваивания).

!ship.cmd.getwarebest.std
Версия: 1
Для версии ScE: 11
Описание: Стандартная команда корабля «Взять товар по лучшей цене»
Аргументы:
1: ware, Var/Ware, 'ware'
Исходный текст:

001 [THIS] ->set command: COMMAND_GET_WARE_BEST target=$ware target2=null par1=null par2=null
002 Просто пустая строка (NOP)
003 @ =[THIS] ->call script '!trade.loop.getwarebest': ware=$ware

Устанавливаем целью команды COMMAND_GET_WARE_BEST товар заданный переменной $ware, присваиваем цели номер два и дополнительным параметрам значение null (т.е. нет значения). Вызываем скрипт '!trade.loop.getwarebest' с аргументом $ware.

!trade.loop.getwarebest
Версия: 1
Для версии ScE: 11
Описание: Поиск и покупка товара, возвращение обратно
Аргументы:
1: ware, Var/Ware, 'ware'
Исходный текст:

001 skip if [HOMEBASE] Если для текущего корабля задана база пропускаем следующую строку
002 return null Возврат в вызывавший скрипт (база не задана). Команда return в данном случае возвращает пустое, «неопределенное» значение (в нашем примере оно все равно нигде не анализируется)
003 skip if [HOMEBASE] ->can buy ware $ware Пропустить следующую строку, если база может покупать товар заданный переменной $ware
004 return null Возврат в вызывавший скрипт (база не может покупать указанный товар)
005
006 while 1 «Вечный» цикл (вместо условия задана константа, выход возможен по return или break)
007 @ =wait randomly from 5000 to 10000 ms Ждем случайное число ms от 5000 до 10000 (5-10 с) (во-первых, так просят делать ребята из Egosoft’а (такие задержки необходимы, чтобы куча скриптов могла выполнятся одновременно не мешая друг-другу), во вторых возможно это уже не первый виток цикла, и мы просто ждем пока «ситуация изменится» (упадет цена, накопится достаточное кол-во товара, появится свободное место для товара на станции, появятся деньги, etc.)
008
009 $homebase=[HOMEBASE] Присваиваем переменной $homebase базу, заданную для корабля, на котором выполняется этот скрипт
010 skip if $homebase Еще раз проверяем существует ли база, (мы ведь ждали 5-10 с и, возможно, это уже не первый виток цикла, за это время её уже могли уничтожить)
011 return null Возврат в вызывавший скрипт (база не существует)
012 $env=$homebase->get environment Получить «окружение» базы, (т.е. объект типа «сектор») и присвоить его переменной $env
013
014 $amount=$homebase->get free amount of ware $ware in cargobay Получить объем оставшегося свободного места на станции для товара ware$ и присвоить его переменной $amount
015 skip if $amount>0 Если объем оставшегося места больше 0, пропускаем следующую строку
016 continue Запускаем новый виток цикла (т.е. переходим в строку 006, объем оставшегося места равен 0)
017
018 $money=$homebase->get money Получить количество денег на станции и присвоить его переменной $money
019 $price =$homebase->get price of ware $ware Получить цену установленную на станции для товара $ware
020 skip if $price>0 Если установлена не нулевая цена – пропускаем следующую строку
021 continue Запускаем новый виток цикла (т.е. переходим в строку 006) (цена нулевая)
022
023 $resnum=$homebase->get number of resources Получить количество типов ресурсов, потребляемых станцией и присвоить его переменной $resnum
024 skip if $resnum<=3 Если количество различных типов ресурсов потребляемых станцией меньше или равно 3, пропускаем следующую строку 025 $resnum=3 Присваиваем переменной $resnum значение равное 3 (станция потребляет больше трех типов ресурсов и мы принудительно присваиваем переменной число 3, для упрощения расчетов)
026 if $resnum==0 Если количество потребляемых типов ресурсов равно 0 (нет первичных ресурсов, например, фабрика батареек), то переходим в строку 027, иначе в строку 029. Обратите внимание, что проверка на равенство выглядит именно как «==», в то время как «=» является оператором присваивания
027 $mult=50 Присваиваем переменной $mult значение равное 50
028 else Условие ложно
029 $mult=140/$resnum Присваиваем переменной $mult значение равное 140/$resnum
030 end Конец условного оператора из строки 026
031 $goodamount=[$money/$price]*$mult/100 Подсчитываем «правильный» остаток свободного места, которое должно быть на станции и присваиваем его переменной $goodamount
032 skip if $goodamount>0 Если «правильный» остаток свободного места больше 0, то пропускаем следующую строку
033 continue Запускаем новый виток цикла (т.е. переходим в строку 006), если «правильный» остаток равен 0 (нет денег на станции для закупки)
034 skip if $amount<=$goodamount Если действительный остаток свободного места меньше, чем «правильный», пропускаем следующую строку
035 $amount =$goodamount Присваиваем переменной $amount значение «правильного» остатка
036
037 $free=[THIS]->get free amount of ware $ware in cargobay Получить объем оставшегося свободного места на корабле для товара $ware и присвоить его переменной $free
038 skip if $amount<=$free Если рассчитанное количество товара меньше, либо равно количеству товара, которое может загрузить в трюм корабль, пропускаем следующую строку
039 $amount=$free Присваиваем переменной $amount количество товара, которое может загрузить в трюм корабль
040 skip if $amount>0 Если в результате получилось количество больше 0, пропускаем следующую строку
041 continue Запускаем новый виток цикла (т.е. переходим в строку 006) – получилось нулевое количество товара (например, трюм корабля заполнен другим товаром)
042
043 $jumps=$homebase->get max trade jumps Получить максимальное количество прыжков за товаром, заданное на станции установленной как база для корабля и присвоить его переменной $jumps
044 $station=find station: product $ware with best price: max.price=$price, amount=$amount, max.jumps=$jumps, startsector=$env, trader=[THIS] Найти станцию удовлетворяющую следующим условиям: станция производит товар $ware, с наименьшей ценой, не превышающей $price, с количеством товара не меньше $amount, находящуюся не более чем в $jumps прыжках от сектора $env, с которой мог бы торговать корабль [THIS] (текущий); и присвоить её идентификатор переменной $station
045 skip if $station Если станция была найдена (получен не нулевой идентификатор), то пропускаем следующую строку
046 continue Запускаем новый виток цикла (т.е. переходим в строку 006), StationID равен 0
047
048 @=[THIS]->call script '!trade.getwareandreturnhome':ware=$ware destination station=$station amount=$amount max.price=$price Вызываем скрипт !trade.getwareandreturnhome с аргументами $ware, $station, $amount, $price (см. аргументы скрипта !trade.getwareandreturnhome)
049
050 end Запускаем новый виток цикла (т.е. переходим в строку 006) и так до тех пор, пока корабль не получит новую команду или какой-либо сигнал с более высоким приоритетом)

!trade.getwareandreturnhome
Версия: 1
Для версии ScE: 11
Описание: Взять товар и вернутся домой
Аргументы:
1: ware, Var/Ware, 'ware'
2: station, Var/Station/Carrier, 'destination station'
3: amount, Var/Number, 'amount'
4: maxprice, Var/Number, 'max.price'

Исходный текст:

001 [THIS]->set wanted ware count to $amount
002 [THIS]->set wanted ware to $ware
003
004 skip if [HOMEBASE]!=$station Пропустить следующую строку, если найденная нами станция не является базой заданной для корабля
005 return null Возврат в вызывавший скрипт (найденная нами станция является базой заданной для корабля)
006
007 while 1 «Вечный» цикл (выход возможен по return или break)
008 @=wait randomly from 100 to 200 ms Ждем случайное число ms от 100 до 200
009
010 skip if [HOMEBASE] Если для текущего корабля задана (существует) база, пропускаем следующую строку
011 return null Возврат в вызывавший скрипт (база не существует)
012
013 skip if $station->exists Пропустить следующую строку, если станция назначения существует
014 break Прервать выполнение цикла, управление перейдет в строку 027 – попытка вернутся на базу, станции уже не существует
015
016 if [DOCKEDAT]==$station Если корабль пристыкован к станции назначения, то переходим в строку 017, иначе в строку 024
017 skip if $maxprice>0 Если переменная $maxprice больше нуля, то пропустить следующую строку
018 $maxprice=null Присвоить переменной $maxprice неопределенное значение (0 «ноль» и null совсем не одно и тоже, см. Переменные) в данном случае подразумевается «покупать по любой цене»
019 skip if $amount>0 Если желаемое количество (переменная $amount) больше нуля, пропустить следующую строку
020 $amount=[THIS]->get free amount of ware $ware in cargobay Получить объем оставшегося свободного места на корабле для товара $ware и присвоить его переменной $amount
021 @=[THIS]->buy $amount units of $ware to a max. price of $maxprice Cr Купить товар $ware в количестве $amount по цене не выше $maxprice
022 break Прервать выполнение цикла, управление перейдет в строку 027 – попытка вернутся на базу
023 else
024 @=[THIS]->call script '!move.movetostation': station=$station Вызвать скрипт !move.movetostation с аргументом $station
025 end Конец условного оператора из строки 016
026 end Конец витка цикла из строки 007
027
028 @=wait randomly from 10000 to 20000 ms Ждем случайное число ms от 10000 до 20000 (10-20 с)
029
030 * fly home if possible Просто комментарий (пример: лететь домой, если возможно)
031 while [ENVIRONMENT]!=[HOMEBASE] Цикл с условием: пока «окружение» (сектор/станция) корабля не равно («!=») заданной для корабля базе (т.е. цикл завершится как только корабль окажется на базе)
032 @ =wait randomly from 100 to 200 ms Ждем случайное число ms от 100 до 200
033 skip if [HOMEBASE] Если для текущего корабля задана (существует) база пропускаем следующую строку
034 return null Возврат в вызывавший скрипт (база не существует)
035 @=[THIS]->fly to home base Лети домой, птичка!
036 end Конец витка цикла из строки 031
037
038 =[THIS]->unload $amount units of $ware Выгрузить товар $ware в количестве $amount
039 return null Возврат в вызывавший скрипт

!move.movetostation
Версия: 1
Для версии ScE: 11
Описание: Перемещение корабля на станцию или авианосец
Аргументы:
1: targetstation , Var/Station/Carrier , 'station'

Исходный текст:

001 skip if $targetstation->is docking possible of [THIS] Пропустить следующую строку, если стыковка со станцией назначения возможна
002 return null Возврат в вызывавший скрипт (стыковка невозможна)
003
004 while 1 «Вечный» цикл (выход возможен по return или break)
005 skip if $targetstation->exists Пропустить следующую строку, если станция назначения существует
006 break Прервать выполнение цикла, управление перейдет в строку 016, выполнение скрипта завершится, произойдет возврат в вызывавший скрипт (станции уже не существует)
007
008 $dockedat =[THIS]->is docked
009 if $targetstation==$dockedat
010 break Прервать выполнение цикла, управление перейдет в строку 016, выполнение скрипта завершится, произойдет возврат в вызывавший скрипт (корабль пристыкован к станции назначения)
011 end Конец условного оператора из строки 009
012
013 @=[THIS]->fly to station $targetstation Лететь на станцию заданную переменной $targetstation
014 @=wait randomly from 100 to 200 ms Ждем случайное число ms от 100 до 200
015 end Конец витка цикла из строки 004 (т.е. цикл будет выполнятся пока станция назначения существует и пока корабль к ней не пристыкован)

Назад к оглавлению
Денис Кузьмин a.k.a. Mad_Kuzia
К началу раздела | Наверх страницы Сообщить об ошибке
X2 - Скрипты - ScE - Примеры скриптов
Все документы раздела: Главная |


Дизайн Elite Games V5 beta.18
EGM Elite Games Manager v5.17 02.05.2010