Йо. Этот тутор предназначен для более-менее соображающих в программировании. В нашем случае мы будем учиться работать с битами. На первый взгляд это выглядит страшно и непонятно, но если вникнуть - это значительно облегчит вам работу..
И так, для начала ознакомьтесь с побитовыми операторами.
А теперь попробуем начать использовать их, на примере давайте заменим банальные лицензии. Например у нас их три - на лодку воздух и авто.
Создаем нашу переменную в которой записаны биты.
Как мы знаем 0 - false, то есть ложь; 1 - true, то есть истина. В нашем случае будет также - 0 есть лицензия, 1 - нету.PHP код:
new lics = 0b000;
Внимание! Биты как и массив начинаются с нулевого!
Давайте попробуем присвоить значение лицензии на авто - 1
Как мы это сделаем:
^ - это оператор "Исключающее или", почему мы используем именно его? Потому-что если вы захотите инвертировать сразу несколько битов - он нам в этом поможет.PHP код:
lics ^= (1<<0);
И так, мы инвертируем первый бит справа налево, т.е
Как было:
Как стало:PHP код:
0b000
Окей, с этим разобрались.PHP код:
0b001
А если нам нужно присвоить сразу несколько значений, как быть?
Решение:
(1<<0) мы присваиваем нулевому биту слева значение 1, инверсия.PHP код:
lics ^= ((1<<0)|(1<<1)|(1<<2));
(1<<1) если вы ещё не поняли почему первая цифра 1 - мы сдвигаемся на один бит влево; 1 - инвертируем первый бит читая справа налево.
(1<<2) тоже самое что и все выражения выше, только уже операция производится со вторым битом.
Тем самым мы произвели инверсию битов. Т.е если у нас было 000, мы вывели 111. ( также и наоборот )
Дальше идет проверка на лицензии.
Например, узнаем есть ли у нас лицензия на автомобиль
Поясняю, мы проверяем почти также, как и устанавливаем. Т.е на сдвигаем на один бит влево ( в проверке ) и проверяем нулевой бит справа налево. Если он не равен нулю, значит лицензия есть. == 1 ставить не рекомендую.PHP код:
if((lics & (1<<0)) == 0) return SendClientMessage(playerid,0xFF0000FF,"У вас нет лицензии на автомобиль");
То же что и выше, только проверяем уже второй битPHP код:
if((lics & (1<<1)) == 0) return SendClientMessage(playerid,0xFF0000FF,"У вас нет лицензии на воздушный транспорт");
Как примерно это будет выглядеть в моде?:
p.s: Если хотите, можете юзать >> слева направоPHP код:
new lics[MAX_PLAYERS];
callback PlayerReg(playerid) { // callback - фаш коллбек присвоения данных при коннекте ( обнуление )
lics[playerid] = 0b000;
}
CMD:givelicense(playerid,params[]) {
if(sscanf(params,"u",params[0])) return SendClientMessage(playerid,-1,"/givelicense [id]");
lics[params[0]] ^= (1<<0);
SendClientMessage(playerid,-1, ((lics[params[0]] & (1<<0)) != 0) ? ("Лицензия на авто получена!") : ("Лицензия на авто изъята!"));
return true;
}
Также D_C предложил следующий варинт:
В самом начале сделать перечисление, чтобы не париться с номерами лицензий:
затем при сдвигах использовать элементы этого перечисления:PHP код:
enum
{
LICENSE_DRIVING = 0,
LICENSE_BOATING,
LICENSE_PILOT
};
PHP код:
lics[targetid] |= (1 << LICENSE_DRIVING);
Вариант Londlem'a:
Также, чтобы не смещать каждый раз, лучше сделать смещение прямо в энумераторе.
Далее просто используем битовый оператор или ( |= ) и название константы:PHP код:
enum(<<= 1)
{
LICENSE_DRIVING = 1, // 1
LICENSE_BOATING, // 2
LICENSE_PILOT // 4
};
И проверять на наличие одной из лицензии почти также:PHP код:
lics[targetid] |= LICENSE_DRIVING;
Разницы почти никакой нет, разве что, не нужно каждый раз смещать, удобнее.PHP код:
if((lics[targetid] & LICENSE_DRIVING) != 0)
// code
Делаем сохранение \ загрузку ( MySQL ):
Для этого уже мы будем присваивать не 0b000, а 0 ( тоже самое что и 000 )
Мы будем загружать целое число также как и сохранять, а менять уже в нем биты.
Я предлагаю вам создать в вашем массиве игроков переменную Licenses, дабы было удобнее.
Загружаем:
Player - ваш массив игрокаPHP код:
Player[playerid][Licenses] = cache_get_field_content_int(0, "licenses", connectionHandle);
Licenses - наши лицензии
"licenses" - поле в БД где хранится наша переменная
connectionHandle - переменная вашего соединения
Сохраняем:
accounts - ваша таблица с аккаунтамиPHP код:
new query[81+1]; // 81 на запрос; Одну ячейку отдаем машине
mysql_format(connectionHandle,query,80,"UPDATE `accounts` SET `licenses` = '%i' WHERE `Name` = '%s'",Player[playerid][Licenses],name);
mysql_tquery(connectionHandle,query,"","");
licenses - ваше поле в бд для сохранении нашей переменной
name - переменная определяющая имя игрока. Я предлагаю использовать удобный вариант - в массив игрока добавляем массив Name, который будет равен макс.значению имени игрока (24), далее в OnPlayerConnect присваиваем переменной значение нашего имени, думаю вы поняли как это сделать. Ну и использовать можно как Player[playerid][Name], либо создать макрос #define Name(%0) Player[%0][Name]. Это удобно и к тому же не нужно лишний раз создавать эти ненужные переменные. И так, тут думаю все ясно, посылаем запрос в таблицу accounts с нашими параметрами.
Такие пироги, легко и просто, не правда ли?
Автор: georJik
Тема будет дополняться...