А можно, как вариант, раскидать всё это дело в массив, прибегнув тем самым к нормальной форме в MYSQL.
#if !defined MAX_BIRTHDAY_DATE
#define MAX_BIRTHDAY_DATE (3)
#endif
#if !defined GetPlayerBirthdayDate
#define GetPlayerBirthdayDate(%0,%1) g_player_birthday_date[%0][%1]
#endif
enum
{
BIRTHDAY_DATE_TYPE_DAY,
BIRTHDAY_DATE_TYPE_MONTH,
BIRTHDAY_DATE_TYPE_YEAR
}
/* ко всем массивам */
new g_player_birthday_date[MAX_PLAYERS][MAX_BIRTHDAY_DATE] = {{-1, ...}, ...};
/* функция, возвращающая единицу в случае, если указаный массив имеет заполнены все ячейки */
stock IsArrayValid(const array[])
{
new count,
size = sizeof array;
for(new idx; idx < size; idx ++)
{
if(array[idx] == -1)
continue;
count ++;
if(count == size)
break;
}
return (count == size)
/* разделение, но придётся накатить новую версию ссканфа, дабы стала доступна возможность использовать звёздочку для того, чтобы узнать итоговую длину массива, куда запишется результат */
new temp_array[sizeof g_player_birthday_date[]] = {-1, ...},
size = sizeof temp_array;
sscanf(inputtext, "p<.>a<i>[*]", size, temp_array);
if(IsArrayValid(temp_array))
{
for(new idx; idx < size; idx ++)
OperatePlayerBirthdayDate(playerid, idx, temp_array[idx]);
}
/* получение данных. Думаю, не нужно объяснять что и куда вставлять */
stock LoadPlayerBirthdayDate(playerid)
{
new fmt_str[] =
{
"SELECT * FROM birthday_date bd"\
" WHERE bd.user_id=%d ORDER BY bd.slot ASC"
},
result_str[sizeof fmt_str + (- 2 + 11)];
format(result_str, sizeof result_str, fmt_str, /* функа или массив, получающие ид игрока в базе */);
mysql_tquery
(
/* ид коннекта*/,
result_str,
"@__OnPlayerLoadBirthdayDate",
"d", playerid
);
return (!mysql_errno() ? 1 : 0);
}
@__OnPlayerLoadBirthdayDate(playerid);
@__OnPlayerLoadBirthdayDate(playerid)
{
for(new idx, slot; idx < cache_num_rows(); idx ++)
{
cache_get_value_name_int(idx, "slot", slot);
if((slot - 1) == -1)
return 0;
cache_get_value_name_int(idx, "date", g_player_birthday_date[playerid][slot - 1]);
}
return 1;
}
stock IsPlayerBirthdayDateValid(playerid, slot)
return (GetPlayerBirthdayDate(playerid, slot) != -1);
/* В случае, если is_player_birthday_date_valid будет равен единице, тогда логично предположить, что существует дата под указаным слотом. Например, захотелось изменить день регистрации паспорта: тогда обновиться первый слот. В ином случае добавит данные в таблицу, если они отсутствуют, то бишь если паспорт не зарегистрирован */
stock OperatePlayerBirthdayDate(playerid, slot, date)
{
new fmt_str[] =
{
"UPDATE birthday_date bd SET bd.date=%d"\
" WHERE bd.slot=%d AND bd.user_id=%d"
},
result_str[sizeof fmt_str + (- 2 + 4) + (- 2 + 1) + (- 2 + 11)],
is_player_birthday_date_valid = IsPlayerBirthdayDateValid(playerid),
user_id = /* функа или элемент перечисления, получающие ид игрока в базе */;
format
(
result_str, sizeof result_str,
is_player_birthday_date_valid ?
fmt_str : ("INSERT INTO birthday_date(user_id,slot,date)"\
" VALUES(%d,%d,%d)"),
is_player_birthday_date_valid ? date : user_id,
slot + 1,
is_player_birthday_date_valid ? user_id : date
);
mysql_tquery(/* ид коннекта */, result_str, "", "");
return (!mysql_errno() ? 1 : 0);
}
/* и потом, например, можно написать такую функцию, записывающую данные о текущей дате регистрации в массив */
stock GetPlayerBirthdayDateEx(playerid, const buffer[11])
{
format
(
buffer, sizeof buffer,
"%02d.%02d.%04d",
GetPlayerBirthdayDate(playerid, BIRTHDAY_DATE_TYPE_DAY),
GetPlayerBirthdayDate(playerid, BIRTHDAY_DATE_TYPE_MONTH),
GetPlayerBirthdayDate(playerid, BIRTHDAY_DATE_TYPE_YEAR)
);
}