Как и обещал, начинаю урок - как сделать систему домов с нуля. Так как давно не занимался Pawno, то это мероприятие может затянуться на долго. Но я ни куда не спешу. Что бы лучше всё вспомнить, систему буду писать на New.pwp.
Если что то не так, пишите в этой теме.
И так начнём. Сначала сделаем простую регистрацию на mxini
- Регистрация
- Для начала подключаем инкуд mxini, для этого ко всем #include добавляем:
Code: Select all
#include <mxini>
Далее создаём переменные для игрока, для этого после всех инклудов вставляем;Code: Select all
enum pInfo {
pMoney, // Сохраняет кол-во денег.
pHouse,// ID первого дома
pHouse1,// ID второго дома
pHouse2,// ID третьего дома
pNHouse // кол-во домов у игрока (Последняя строка без запятой)
};
new PlayerInfo[MAX_PLAYERS][pInfo];
Для вывода меню, в паблик - public OnPlayerConnect(playerid)Code: Select all
public OnPlayerConnect(playerid)
{
new PlayerName[500];
GetPlayerName(playerid,PlayerName,sizeof(PlayerName)); //узнаем ник
new account[128];
format(account,sizeof(account),"Users/%s.ini",PlayerName); // ищем аккаунт
// Если нашли, то выводим окно "Авторизация"
if(fexist(account)) return ShowPlayerDialog(playerid,2,DIALOG_STYLE_INPUT, "Авторизация", "Введите свой пароль", "Войти", "");
else // Если игрок найден, то авторизация
{
ShowPlayerDialog(playerid,1,DIALOG_STYLE_INPUT, "Регистрация", "Введите пароль:", "Войти", "");
}
PlayerInfo[playerid][pMoney] = 0; // При регистрации 0 денег
PlayerInfo[playerid][pHouse] = 0; // 0 домов...
PlayerInfo[playerid][pHouse1] = 0;
PlayerInfo[playerid][pHouse2] = 0;
PlayerInfo[playerid][pNHouse] = 0;
return true;
}
А теперь создаём действия для этих меню.
В паблик public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])Code: Select all
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
new PlayerName[MAX_PLAYER_NAME];
GetPlayerName(playerid,PlayerName,sizeof(PlayerName));// Узнаем ник игрока
new account[128];
format(account,sizeof(account),"Users/%s.ini",PlayerName);// Создаем аккаунт
if(dialogid == 1) // Регистрация
{
if(!strlen(inputtext)) return ShowPlayerDialog(playerid,1,DIALOG_STYLE_INPUT, "Регистрация", "Придумайте себе пароль", "Войти", "");
if(response)
{
GetPlayerName(playerid,PlayerName,sizeof(PlayerName)); //узнаем ник
format(account,sizeof(account),"Users/%s.ini",PlayerName);//ищем акк
if(fexist(account)) return ShowPlayerDialog(playerid,2,DIALOG_STYLE_INPUT, "Авторизация", "Введите свой пароль", "Войти", "");
new iniFile = ini_createFile(account); // Создаем аккаунт
if(iniFile < 0) ini_openFile (account); // Если файл пустой, то откроем и ...
{
ini_setString(iniFile,"Password",inputtext); // Запишем пароль для игрока
ini_setInteger(iniFile, "Money", 0); // Запишем кол-во денег для игрока
ini_setInteger(iniFile, "House", 0); //дома
ini_setInteger(iniFile, "House1", 0);
ini_setInteger(iniFile, "House2", 0);
ini_setInteger(iniFile, "NHouse", 0);
ini_closeFile(iniFile); // Закроем файл
}
}
else //проверка Esc'ейпа
{
ShowPlayerDialog(playerid,1,DIALOG_STYLE_INPUT, "Регистрация", "Придумайте себе пароль", "Войти", "");
}
}
if(dialogid == 2)
{
if(!strlen(inputtext))return ShowPlayerDialog(playerid,2,DIALOG_STYLE_INPUT, "Авторизация", "Введите свой пароль:", "Войти", "");
if(response)// Проверка на кнопку "ОК" и Enter
{
new password[64];
GetPlayerName(playerid,PlayerName,sizeof(PlayerName));
format(account,sizeof(account),"Users/%s.ini",PlayerName);
new iniFile = ini_openFile(account);
{
ini_getString(iniFile, "Password",password); // Узнаём пароль аккаунта.
if(!strcmp(inputtext, password, true))
{
ini_getInteger(iniFile,"Money", PlayerInfo[playerid][pMoney]); // Запишем кол-во денег игроку
ini_getInteger(iniFile,"House",PlayerInfo[playerid][pHouse]); // дома
ini_getInteger(iniFile,"House1",PlayerInfo[playerid][pHouse1]);
ini_getInteger(iniFile,"House2",PlayerInfo[playerid][pHouse2]);
ini_getInteger(iniFile,"NHouse",PlayerInfo[playerid][pNHouse]);
GivePlayerMoney(playerid, PlayerInfo[playerid][pMoney]); // Количество денег у игрока
format(account, sizeof(account), "Вы вошли в свой аккаунт: "%s".",PlayerName);
SendClientMessage(playerid, 0xFFFF00FF,account);// Напишет в чат
ini_closeFile(iniFile);// закроем файл
}
else//проверка Esc'ейпа
{
ShowPlayerDialog(playerid,2,DIALOG_STYLE_INPUT, "Авторизация", "Введите свой пароль:", "Войти", "");
SendClientMessage(playerid, 0xF60000AA, "Неверный пароль. Попробуйте ещё раз.");
}
}
}
else//проверка Esc'ейпа
{
ShowPlayerDialog(playerid,2,DIALOG_STYLE_INPUT, "Авторизация", "Введите свой пароль:", "Войти", "");
}
}
return true;
}
Создаём новый паблик - public SaveAccounts(), ко всем пабликам добавимCode: Select all
forward SaveAccounts();
public SaveAccounts()
{
for(new f; f < GetMaxPlayers(); f++)
{
if(!IsPlayerConnected(f))continue;
SaveAccount(f);
}
}
В конце мода добавляем сток, который и будет выполнять все функции сохранения и записи данныхCode: Select all
stock SaveAccount(playerid) // Сохраняет данные
{
new PlayerName[MAX_PLAYER_NAME], account[128];
GetPlayerName(playerid,PlayerName,sizeof(PlayerName));
format(account,sizeof(account), "Users/%s.ini", PlayerName);
new iniFile = ini_openFile(account);// откр. файл
ini_setInteger(iniFile, "Money", GetPlayerMoney(playerid));// записываем
ini_setInteger(iniFile, "House", PlayerInfo[playerid][pHouse]);
ini_setInteger(iniFile, "House1", PlayerInfo[playerid][pHouse1]);
ini_setInteger(iniFile, "House2", PlayerInfo[playerid][pHouse2]);
ini_setInteger(iniFile, "NHouse", PlayerInfo[playerid][pNHouse]);
ini_closeFile(iniFile);// закрываем
return 1;
}
Для сохранения при выходе из игры, в паблик public OnPlayerDisconnect(playerid, reason)Code: Select all
public OnPlayerDisconnect(playerid, reason)
{
SaveAccount(playerid); // Сохранение аккаунтов
return true;
}
С модом работу мы закончили, теперь открываем папку с сервером и в папке scriptfiles создаём новую папку users, в которой и будут сохраняться файлы игроков.
Всё! Заходим в игру регистрируемся, выходим из игры. Открываем папку scriptfiles --> users и видим там файлик ваш ник.ini.Code: Select all
Password = 123
Money = 0
House = 0
House1 = 0
House2 = 0
NHouse = 0
Можно сразу добавить денег в строку Money = 0 (Money = 1000000)
Ну вот, с регистрацией закончили. Теперь давайте создадим *Главное меню* на кнопку Alt
- Главное меню
- В паблик - public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
Code: Select all
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
if ((newkeys==1024))
{
ShowPlayerDialog(playerid,3,DIALOG_STYLE_LIST,"Главное меню","Дома", "Выбрать", "Выход");
}
return true;
}
Пока отложу
Теперь добавим в мод некоторые функции, которые нам понадобятся в дальнейшем.
- Функции
- Сначала в папке scriptfiles создадим папку House и вставим туда такой файлик - House.ini (на 10 домов)следующего содержания:
Code: Select all
1 = Дом|0|1000|Нет|-2075.5388|-60.7090|35.3203|2365.419921|-1131.849975|1050.880004|1|0
2 = Дом|0|1000|Нет|-2072.8391|-60.6326|35.3203|2365.419921|-1131.849975|1050.880004|2|0
3 = Дом|0|1000|Нет|-2069.2888|-61.1034|35.3203|2365.419921|-1131.849975|1050.880004|3|0
4 = Дом|0|1000|Нет|-2064.4272|-60.6843|35.3203|2365.419921|-1131.849975|1050.880004|4|0
5 = Дом|0|1000|Нет|-2060.5737|-60.8517|35.3203|2365.419921|-1131.849975|1050.880004|5|0
6 = Дом|0|1000|Нет|-2056.6555|-60.8095|35.3203|2365.419921|-1131.849975|1050.880004|6|0
7 = Дом|0|1000|Нет|-2051.7888|-60.7943|35.3203|2365.419921|-1131.849975|1050.880004|7|0
8 = Дом|0|1000|Нет|-2048.2791|-60.8573|35.3203|2365.419921|-1131.849975|1050.880004|8|0
9 = Дом|0|1000|Нет|-2044.1116|-60.7381|35.3203|2365.419921|-1131.849975|1050.880004|9|0
10 = Дом|0|1000|Нет|-2040.5066|-60.7776|35.3203|2365.419921|-1131.849975|1050.880004|10|0
Разберём его по частям:
1 - ID дома
1 = Дом - название дома
1 = Дом|0 - резервная строка (про запас )
1 = Дом|0|1000|Нет - владелец
1 = Дом|0|1000|Нет|-2075.5388|-60.7090|35.3203 - следующие 3 - координаты пикапа и текста
1 = Дом|0|1000|Нет|-2075.5388|-60.7090|35.3203|2365.419921|-1131.849975|1050.880004 - следующие 3 - координаты интерьера дома
1 = Дом|0|1000|Нет|-2075.5388|-60.7090|35.3203|2365.419921|-1131.849975|1050.880004|1 - виртуальный мир интерьера (что бы владельцы не пересекались)
1 = Дом|0|1000|Нет|-2075.5388|-60.7090|35.3203|2365.419921|-1131.849975|1050.880004|1|0 - продан или нет 0 - нет, 1 - продан.
Добавим инклуд #include <streamer>
В конец мода сток (что то связано с разбивкой строк):Code: Select all
stock split(const strsrc[], strdest[][], delimiter)
{
new i, li;
new aNum;
new len;
while(i <= strlen(strsrc)){
if(strsrc[i]==delimiter || i==strlen(strsrc)){
len = strmid(strdest[aNum], strsrc, li, i, 128);
strdest[aNum][len] = 0;
li = i+1;
aNum++;
}
i++;
}
return true;
}
и сток ConvertNumbers (добавляет точки в цифры - 1.000.000)Code: Select all
stock ConvertNumbers(num,delimeter[2],size = 3)
{
new result[50];
new x = -1;
valstr(result,num);
for(new i = strlen(result); i > 0; i--)
{
x++;
if(x == size){ strins(result,delimeter,i); x = 0; }
}
return result;
}
и ещё сток stock GetPlayerID(const Name[]) (узнать ID по нику)Code: Select all
stock GetPlayerID(const Name[])
{
for(new i; i<MAX_PLAYERS; i++)
{
if(IsPlayerConnected(i))
{
new pName[MAX_PLAYER_NAME];
GetPlayerName(i, pName, sizeof(pName));
if(strcmp(Name, pName, true)==0)
{
return i;
}
}
}
return -1;
}
И сама система:
- Начало
- Создаём переменные для домов, после new PlayerInfo[MAX_PLAYERS][pInfo]; вставляем:
Code: Select all
#define MAX_HOUSE 11//для 10 домов (если надо больше - увеличивайте на своё кол-во +1)
new hpid[64];//id пикапов
new HouseSale[MAX_HOUSE]; // иконка продающегося дома
new HouseOwn[MAX_HOUSE]; // иконка купленного дома
new HousePickupSale[MAX_HOUSE]; // Pickup продающегося дома
new HousePickupOwn[MAX_HOUSE]; // Pickup купленного дома
new Text3D: House3DSale[MAX_HOUSE]; // 3D-текст продающегося дома
new Text3D:House3DOwn[MAX_HOUSE]; // 3D-текст купленного дома
enum hHouse
{
hhouseName[128], //0 имя дома
hhouseDohod,//уровень (уже и не помню для чего)
hhousePrice,//цена
hhouseOwner[MAX_PLAYER_NAME],//имя влад
Float:hhousePosX,// координаты чего то(вспомню - напишу)
Float:hhousePosY,
Float:hhousePosZ,
Float:hhouse1PosX,
Float:hhouse1PosY,
Float:hhouse1PosZ,
hworld,// вроде вирт. мир интерьера дома
hClok,//занят или нет
Exit //
};
new HouseSystem[MAX_HOUSE][hHouse];
Создаем паблики сохранения и загрузки домов из файла:Code: Select all
forward LoadHouse();
public LoadHouse()
{
new house = ini_openFile("House/House.ini");
new hinfo[12][128];//где 12 - число значений в файле после ключа, 128 - максимальный размер значения (?)
new hid[64];// для строкового типа id дома
new bstring[256];// для записи полной строки для ключа
new string[256];
for(new i = 1; i < MAX_HOUSE; i++)
{
if(HouseSystem[i][hClok]== 1)
{
Delete3DTextLabel(Text3D:House3DSale[i]);
format(string, 256, "{FF9900}Дом: {FFFFFF}%s\n{00ff00}Владелец: {FFFFFF}%s\n{f984e5}id %d", HouseSystem[i][hhouseName], HouseSystem[i][hhouseOwner], HouseSystem[i][hworld]);
House3DSale[i] = Create3DTextLabel(string, 0xFEFEFEFE, HouseSystem[i][hhousePosX], HouseSystem[i][hhousePosY], HouseSystem[i][hhousePosZ], 40.0, 0, 1);
}
if(HouseSystem[i][hClok]== 0)
{
Delete3DTextLabel(Text3D:House3DOwn[i]);
format(string, 256, "{FF9900}Дом: {FFFFFF}%s\n{00ff00}Владелец: {FFFFFF}%s\n{0096ff}Продаётся\n{ff0000}Стоимость: {FFFFFF}$%s\n{f984e5}id %d", HouseSystem[i][hhouseName], HouseSystem[i][hhouseOwner], ConvertNumbers(HouseSystem[i][hhousePrice],"."), HouseSystem[i][hworld]);
House3DOwn[i] = Create3DTextLabel(string, 0xFEFEFEFE, HouseSystem[i][hhousePosX], HouseSystem[i][hhousePosY], HouseSystem[i][hhousePosZ], 40.0, 0, 1);
}
format(hid, 64, "%d", i);// запишем id дома в строку
ini_getString(house, hid, bstring);// загрузим данные из id дома в строку bstring
split(bstring, hinfo, '|');// разобьём строку bstring и запишем разбитые данные символом | в массив hinfo
strmid(HouseSystem[i][hhouseName], hinfo[0], 0, strlen(hinfo[0]), 256);//название дома
HouseSystem[i][hhouseDohod] = strval(hinfo[1]);// уровень дома
HouseSystem[i][hhousePrice] = strval(hinfo[2]); // цена дома
strmid(HouseSystem[i][hhouseOwner], hinfo[3], 0, strlen(hinfo[3]), 256); // владелец дома
HouseSystem[i][hhousePosX] = floatstr(hinfo[4]);
HouseSystem[i][hhousePosY] = floatstr(hinfo[5]);
HouseSystem[i][hhousePosZ] = floatstr(hinfo[6]);
HouseSystem[i][hhouse1PosX] = floatstr(hinfo[7]);
HouseSystem[i][hhouse1PosY] = floatstr(hinfo[8]);
HouseSystem[i][hhouse1PosZ] = floatstr(hinfo[9]);
HouseSystem[i][hworld] = strval(hinfo[10]);
HouseSystem[i][hClok] = strval(hinfo[11]);
//
}
ini_closeFile(house);
return true;
}
forward SaveHouse();
public SaveHouse()
{
new string[200];
new house = ini_openFile("House/House.ini");
new hid[64];
for(new i = 1; i < MAX_HOUSE; i++)
{
format(string,sizeof(string),"%s|%d|%d|%s|%f|%f|%f|%f|%f|%f|%d|%d",
HouseSystem[i][hhouseName],
HouseSystem[i][hhouseDohod],
HouseSystem[i][hhousePrice],
HouseSystem[i][hhouseOwner],
HouseSystem[i][hhousePosX],
HouseSystem[i][hhousePosY],
HouseSystem[i][hhousePosZ],
HouseSystem[i][hhouse1PosX],
HouseSystem[i][hhouse1PosY],
HouseSystem[i][hhouse1PosZ],
HouseSystem[i][hworld],
HouseSystem[i][hClok]);
format(hid,64,"%d",i);
ini_setString(house,hid,string);
}
ini_closeFile(house);
}