FOnline
 Указатель Классы Функции Переменные Группы Страницы
Препроцессор

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

Препроцессор на входе получает иходный код, написанный программистом, а на выходе выдает переработанный код, полученный с учетом указанных в скрипте директив.

Директивы препроцессора:

#include
#define
#ifdef
#ifndef
#endif

Директива "#include" включает в состав исходного файла содержимое указанного файла. Таким образом, после обработки препроцессором, все строки:

#include "filename"

будут заменены содержимым указанного файла.

Директива "#define" в основном используется для создания констант и макросов:

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

#define MONEY_PID (41)

После такого объявления, в коде скрипта можно использовать строку MONEY_PID вместо прямого указания номера 41, в тех местах, где необходимо указать пид, используемый в качестве денег. После обработки препроцессором, все строки "MONEY_PID" будут заменены на "(41)"

Пример макроса:

#define _CritMoveItem #(cr,item,toSlot) cr.MoveItem(item.Id,item.GetCount(),toSlot)

После такого объявления, встреченные в исходном коде строки:

_CritMoveItem(player,weapon,SLOT_ARMOR);

будут заменены на:

player.MoveItem(weapon.Id,weapon.GetCount(),(3))

При этом, строка SLOT_ARMOR будет заменена на (3), так как в файле _defines.fos объявлена директива "#define SLOT_ARMOR (3) // Armor slot"

"#ifdef" - открытие блока "если определено"
"#ifndef" - открытие блока "если не определено"
"#endif" - закрытие блока
Директивы #ifdef, #ifndef и #endif существуют для еще большего удобства скриптера.

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

#define __DEBUG__
#ifdef __DEBUG__
Log(.......);
#endif
....
....
#ifdef __DEBUG__
SayId(.......);
#endif
....
....
#ifndef __DEBUG__
StartAttack(.......);
#endif

В данном примере в исходном коде после обработки препроцессором встретятся строки "Log(.......);" и "SayId(.......);", однако, если убрать или закомментировать строку "#define <strong>DEBUG</strong>", то в коде будет только строка "StartAttack(.......);"

Помимо обработки директив, препроцессор убирает из исходного кода все комментарии, так как они не важны для компилятора.
Стоит так же отметить, что при сообщении компилятором об ошибках в коде, он выдает номера строк и символов в коде после обработки препроцессором.
Обработанные препроцессором скрипты появляются при запуске сервера и находятся в папке скриптов с расширениями "fosp", если необходимо посмотреть полученный код при ручном компилировании, необходимо передать компилятору имя файла, куда будет помещен полученный код, с помощью параметра "-p".

Типичная функция после обработки препроцессором:

uint GetKeyId(Critter&cr,uint lockerId)
{
if(lockerId==0||(0x80000000|(cr.Id))==lockerId||(0x40000000|(cr.Id))==lockerId)return 0;
Item@[]keys;
for(uint i=0,j=cr.GetItemsByType((7),keys);i<j;i++)if(keys[i].LockerId==lockerId)return keys[i].Id;
return 0;
}

Исходный вид функции:

uint GetKeyId(Critter& cr, uint lockerId) // Export
{
if(lockerId==0 || _CritFingersDoorId(cr.Id)==lockerId || _CritEyesDoorId(cr.Id)==lockerId) return 0;
Item@[] keys;
for(uint i=0,j=cr.GetItemsByType(ITEM_KEY,keys);i<j;i++) if(keys[i].LockerId==lockerId) return keys[i].Id;
return 0;
}