Активный
- Тема Автор
- #1
Руководство по созданию системы выбора скина для игроков с категориями и предпросмотром.
Структура данных скинов
Инициализация скинов
Меню выбора скина
Предпросмотр скина
Сохранение скина игрока
Команда смены скина
Ограничение скинов по фракциям
Случайный скин
Список всех скинов
Система выбора скина - важная часть игрового процесса. Эти примеры показывают полный функционал работы со скинами с категориями, предпросмотром и ограничениями.
Структура данных скинов
Код:
enum SkinInfo
{
sID,
sName[32],
sCategory,
sPrice,
sGender
}
new SkinData[300][SkinInfo];
new TotalSkins = 0;
new SkinCategories[][32] = {
"Гражданские",
"Полиция",
"Медики",
"Военные",
"Гангстеры",
"Спортсмены"
};
Инициализация скинов
Код:
InitializeSkins()
{
// Гражданские (мужские)
AddSkin(0, "Carl Johnson", 0, 0, 0);
AddSkin(1, "Truth", 0, 0, 0);
AddSkin(2, "Maccer", 0, 0, 0);
// Гражданские (женские)
AddSkin(9, "Millie Perkins", 0, 0, 1);
AddSkin(10, "Denise Robinson", 0, 0, 1);
AddSkin(11, "Helena Wankstein", 0, 0, 1);
// Полиция
AddSkin(280, "Полицейский LS", 1, 0, 0);
AddSkin(281, "Полицейский SF", 1, 0, 0);
AddSkin(282, "Полицейский LV", 1, 0, 0);
AddSkin(283, "Полицейский SWAT", 1, 5000, 0);
// Медики
AddSkin(274, "Медик", 2, 0, 0);
AddSkin(275, "Медик", 2, 0, 1);
// Военные
AddSkin(287, "Солдат", 3, 10000, 0);
AddSkin(285, "Офицер", 3, 15000, 0);
return 1;
}
AddSkin(skinid, name[], category, price, gender)
{
if(TotalSkins >= sizeof(SkinData))
{
return -1;
}
SkinData[TotalSkins][sID] = skinid;
strcpy(SkinData[TotalSkins][sName], name, 32);
SkinData[TotalSkins][sCategory] = category;
SkinData[TotalSkins][sPrice] = price;
SkinData[TotalSkins][sGender] = gender;
TotalSkins++;
return TotalSkins - 1;
}
Меню выбора скина
Код:
ShowSkinMenu(playerid)
{
new string[512] = "Выберите категорию скинов:\n\n";
for(new i = 0; i < sizeof(SkinCategories); i++)
{
format(string, sizeof(string), "%s%d. %s\n", string, i+1, SkinCategories[i]);
}
ShowPlayerDialog(playerid, DIALOG_SKIN_CATEGORY, DIALOG_STYLE_LIST, "Выбор скина", string, "Выбрать", "Отмена");
return 1;
}
ShowSkinList(playerid, category)
{
new string[512], count = 0, list[100];
for(new i = 0; i < TotalSkins; i++)
{
if(SkinData[i][sCategory] == category)
{
format(list, sizeof(list), "%d. %s", SkinData[i][sID], SkinData[i][sName]);
if(SkinData[i][sPrice] > 0)
{
format(list, sizeof(list), "%s ($%d)\n", list, SkinData[i][sPrice]);
}
else
{
strcat(list, "\n");
}
strcat(string, list);
count++;
}
}
if(count == 0)
{
SendClientMessage(playerid, -1, "В этой категории нет скинов");
return 1;
}
SetPVarInt(playerid, "SkinCategory", category);
ShowPlayerDialog(playerid, DIALOG_SKIN_LIST, DIALOG_STYLE_LIST, "Список скинов", string, "Выбрать", "Назад");
return 1;
}
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
if(dialogid == DIALOG_SKIN_CATEGORY)
{
if(response)
{
ShowSkinList(playerid, listitem);
}
return 1;
}
if(dialogid == DIALOG_SKIN_LIST)
{
if(response)
{
new category = GetPVarInt(playerid, "SkinCategory");
new skinIndex = -1, currentIndex = 0;
for(new i = 0; i < TotalSkins; i++)
{
if(SkinData[i][sCategory] == category)
{
if(currentIndex == listitem)
{
skinIndex = i;
break;
}
currentIndex++;
}
}
if(skinIndex != -1)
{
if(SkinData[skinIndex][sPrice] > 0)
{
if(GetPlayerMoney(playerid) < SkinData[skinIndex][sPrice])
{
new string[128];
format(string, sizeof(string), "Недостаточно денег. Нужно: $%d", SkinData[skinIndex][sPrice]);
SendClientMessage(playerid, -1, string);
return 1;
}
GivePlayerMoney(playerid, -SkinData[skinIndex][sPrice]);
}
SetPlayerSkin(playerid, SkinData[skinIndex][sID]);
new string[128];
format(string, sizeof(string), "Вы выбрали скин: %s", SkinData[skinIndex][sName]);
SendClientMessage(playerid, -1, string);
PlayerInfo[playerid][pSkin] = SkinData[skinIndex][sID];
}
}
else
{
ShowSkinMenu(playerid);
}
return 1;
}
return 0;
}
Предпросмотр скина
Код:
PreviewSkin(playerid, skinid)
{
if(skinid < 0 || skinid > 299)
{
return 0;
}
SetPlayerSkin(playerid, skinid);
new Float:x, Float:y, Float:z, Float:angle;
GetPlayerPos(playerid, x, y, z);
GetPlayerFacingAngle(playerid, angle);
// Поворот для лучшего обзора
SetPlayerFacingAngle(playerid, angle + 180.0);
new string[128];
format(string, sizeof(string), "Предпросмотр скина ID: %d\nИспользуйте /buyskin чтобы купить", skinid);
SendClientMessage(playerid, -1, string);
SetPVarInt(playerid, "PreviewSkin", skinid);
return 1;
}
CMD:previewskin(playerid, params[])
{
new skinid;
if(sscanf(params, "d", skinid))
{
SendClientMessage(playerid, -1, "Использование: /previewskin [id скина]");
return 1;
}
PreviewSkin(playerid, skinid);
return 1;
}
CMD:buyskin(playerid, params[])
{
if(!GetPVarType(playerid, "PreviewSkin"))
{
SendClientMessage(playerid, -1, "Сначала используйте /previewskin для предпросмотра");
return 1;
}
new skinid = GetPVarInt(playerid, "PreviewSkin");
new skinIndex = -1;
for(new i = 0; i < TotalSkins; i++)
{
if(SkinData[i][sID] == skinid)
{
skinIndex = i;
break;
}
}
if(skinIndex == -1)
{
SendClientMessage(playerid, -1, "Скин не найден в базе");
return 1;
}
if(SkinData[skinIndex][sPrice] > 0)
{
if(GetPlayerMoney(playerid) < SkinData[skinIndex][sPrice])
{
new string[128];
format(string, sizeof(string), "Недостаточно денег. Нужно: $%d", SkinData[skinIndex][sPrice]);
SendClientMessage(playerid, -1, string);
return 1;
}
GivePlayerMoney(playerid, -SkinData[skinIndex][sPrice]);
}
SetPlayerSkin(playerid, skinid);
PlayerInfo[playerid][pSkin] = skinid;
DeletePVar(playerid, "PreviewSkin");
new string[128];
format(string, sizeof(string), "Вы купили скин: %s", SkinData[skinIndex][sName]);
SendClientMessage(playerid, -1, string);
return 1;
}
Сохранение скина игрока
Код:
SavePlayerSkin(playerid)
{
new query[256], name[MAX_PLAYER_NAME];
GetPlayerName(playerid, name, sizeof(name));
format(query, sizeof(query), "UPDATE players SET skin = %d WHERE name = '%e'", PlayerInfo[playerid][pSkin], name);
mysql_query(g_SQL, query);
return 1;
}
LoadPlayerSkin(playerid)
{
new query[256], name[MAX_PLAYER_NAME];
GetPlayerName(playerid, name, sizeof(name));
format(query, sizeof(query), "SELECT skin FROM players WHERE name = '%e'", name);
mysql_query(g_SQL, query);
mysql_store_result();
if(mysql_num_rows() > 0)
{
PlayerInfo[playerid][pSkin] = mysql_fetch_int("skin");
SetPlayerSkin(playerid, PlayerInfo[playerid][pSkin]);
}
else
{
// Скин по умолчанию
PlayerInfo[playerid][pSkin] = 0;
SetPlayerSkin(playerid, 0);
}
mysql_free_result();
return 1;
}
Команда смены скина
Код:
CMD:skin(playerid, params[])
{
ShowSkinMenu(playerid);
return 1;
}
CMD:myskin(playerid, params[])
{
new string[128];
format(string, sizeof(string), "Ваш текущий скин: ID %d", PlayerInfo[playerid][pSkin]);
SendClientMessage(playerid, -1, string);
return 1;
}
Ограничение скинов по фракциям
Код:
CanPlayerUseSkin(playerid, skinid)
{
if(PlayerFaction[playerid][pFaction] == -1)
{
// Гражданские могут использовать только гражданские скины
for(new i = 0; i < TotalSkins; i++)
{
if(SkinData[i][sID] == skinid)
{
if(SkinData[i][sCategory] == 0)
{
return 1;
}
return 0;
}
}
return 0;
}
// Проверка скинов фракции
new factionid = PlayerFaction[playerid][pFaction];
for(new i = 0; i < TotalSkins; i++)
{
if(SkinData[i][sID] == skinid)
{
if(SkinData[i][sCategory] == FactionData[factionid][fSkinCategory])
{
return 1;
}
return 0;
}
}
return 0;
}
SetPlayerSkinSafe(playerid, skinid)
{
if(!CanPlayerUseSkin(playerid, skinid))
{
SendClientMessage(playerid, -1, "Вы не можете использовать этот скин");
return 0;
}
SetPlayerSkin(playerid, skinid);
PlayerInfo[playerid][pSkin] = skinid;
return 1;
}
Случайный скин
Код:
CMD:randomskin(playerid, params[])
{
new category = 0;
if(!isnull(params))
{
category = strval(params);
}
new availableSkins[300], count = 0;
for(new i = 0; i < TotalSkins; i++)
{
if(SkinData[i][sCategory] == category)
{
if(CanPlayerUseSkin(playerid, SkinData[i][sID]))
{
availableSkins[count] = SkinData[i][sID];
count++;
}
}
}
if(count == 0)
{
SendClientMessage(playerid, -1, "Нет доступных скинов в этой категории");
return 1;
}
new randomSkin = availableSkins[random(count)];
SetPlayerSkinSafe(playerid, randomSkin);
new string[128];
format(string, sizeof(string), "Выбран случайный скин: ID %d", randomSkin);
SendClientMessage(playerid, -1, string);
return 1;
}
Список всех скинов
Код:
CMD:skinlist(playerid, params[])
{
new string[512] = "Доступные скины:\n\n";
new count = 0;
for(new i = 0; i < TotalSkins && count < 20; i++)
{
if(CanPlayerUseSkin(playerid, SkinData[i][sID]))
{
format(string, sizeof(string), "%sID %d: %s\n",
string, SkinData[i][sID], SkinData[i][sName]);
count++;
}
}
if(count == 0)
{
strcat(string, "Нет доступных скинов");
}
ShowPlayerDialog(playerid, DIALOG_SKIN_LIST_ALL, DIALOG_STYLE_MSGBOX, "Список скинов", string, "Закрыть", "");
return 1;
}
Система выбора скина - важная часть игрового процесса. Эти примеры показывают полный функционал работы со скинами с категориями, предпросмотром и ограничениями.