Идея хорошая, но реализация, ИМХО, хромает.
Каждый новый макрос здесь - это повторение предыдущего. Разве что GetLicCar реализован не так, как остальные, но это может только ещё больше сбить с толку.
Мало того, если какой-то вид лицензии не объявлен, мне придётся самому лезть в чужой код, разбираться, как он работает, и добавлять макросы для новых лицензий.
Причём не факт, что эти новые макросы будут добавлены правильно. Если я сделаю макрос на основе уже существующего и забуду поменять название, компилятор выдаст варнинг на повторное определение макроса.
Если же забыть поменять значение сдвига (например, вместо "<<5" оставить "<<4"), ошибка останется незамеченной.
В общем, набросал я тут "эталонную" реализацию (кавычки потому, что не мне решать, насколько она эталонная).
Не то, чтобы я хочу заставить вас использовать её в какой-то степени, но надеюсь, что вы изучите её, раз решили взяться за написание инклудов.
PHP код:
// Защита от повторного подключения (актуально при использовании модифицированного компилятора от Zeex).
#if defined PL_LICENSES // Префикс "PL" - сокращение от "Prolific", можете выбрать и другой.
#endinput
#endif
#define PL_LICENSES
#include <a_samp>
// Макросы для работы с флагами.
#if !defined BitGet
#define BitGet(%0,%1)\
(%0) & (1 << (%1))
#endif
#if !defined BitSet
#define BitSet(%0,%1,%2)\
%0 = ((%2) != 0) ? ((%0) | (1 << (%1))) : ((%0) & ~(1 << (%1)))
#endif
#if !defined e_LICENSE_TYPE
// Допускаем возможность самостоятельного объявления лицензий на случай, если пользователю нужен тип лицензии,
// которого нет в инклуде (например, здесь не объявлена лицензия на ведение бизнеса).
enum e_LICENSE_TYPE
{
LICENSE_TYPE_FISHING,
LICENSE_TYPE_DRIVING,
LICENSE_TYPE_PILOT
};
#endif
// Если типов лицензий не больше восьми, можно использовать упакованный массив.
// Спецификатор static ограничивает видимость переменной в пределах инклуда.
static stock licenses[MAX_PLAYERS char];
// Функции для операций с лицензиями.
// Здесь нужны именно функции, а не макросы, чтобы компилятор мог выдать варнинг,
// если, например, вместо "LICENSE_TYPE_FISHING" передать "0".
stock GetPlayerLicenseStatus(playerid, e_LICENSE_TYPE:type)
return BitGet(licenses{playerid}, _:type);
stock SetPlayerLicenseStatus(playerid, e_LICENSE_TYPE:type, bool:active)
return BitSet(licenses{playerid}, _:type, _:active);
stock GivePlayerLicense(playerid, e_LICENSE_TYPE:type)
return BitSet(licenses{playerid}, _:type, 1);
stock TakePlayerLicense(playerid, e_LICENSE_TYPE:type)
return BitSet(licenses{playerid}, _:type, 0);
stock GetPlayerLicenses(playerid)
return licenses{playerid};
stock SetPlayerLicenses(playerid, flags)
return (licenses{playerid} = flags);