![]() |
|
![]() |
![]() |
Новости | Конференция | Чат | База данных | Творчество | Сообщество | О сайте | English |
![]() |
Помощь сайту |
![]() |
![]() |
![]() |
![]() |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ПРИМЕРЫ СКРИПТОВ Ниже будет рассмотрен пример, демонстрирующий стандартную команду «Взять товар по наилучшей цене». Он состоит из нескольких отдельных, логически завершенных скриптов. Почему именно из нескольких? Почему не одним? Ответ на этот вопрос очень прост: как я уже писал в «вступлении», все скрипты будут строится из отдельных кусков – примитивов, например, скрипт !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 (т.е. цикл будет выполнятся пока станция назначения существует и пока корабль к ней не пристыкован) Назад к оглавлению
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
![]() |
![]() |
![]() |
![]() |
Дизайн Elite Games V5 beta.18 EGM Elite Games Manager v5.17 02.05.2010 |
![]() |