PRоFeSSoR

Пишем систему домов с 0-ля

В теме 1 сообщение

Изображение

Начало
Приветствую уважаемые пользователи PAWNO-RUS! Пока у меня есть свободное время, я решил написать урок который будет состоять из нескольких частей. В данном уроке я постараюсь как можно "раскрыто" показать вам как можно написать систему домов для игрового режима с 0 (или для "new.pwn"). Хочу отметить, что для корректной работы системы нам понадобятся 2 библиотеки:
- mxINI: Скачать
- sscanf: zip.gif sscanf.rar [37,51К]

 Поясняю для чего мы будем использовать это: 

- mxINI: для работы с файлами (чтение / запись в файл); 
- sscanf: позволит нам скажем "разделить" и расставить по местам нужную информацию; 

 Небольшое описание системы:

- Динамическая и простая система домов которая отлично подойдет для игровых режимов с 0 (и не только). Очень удобное добавление новых интерьеров в систему. На данный момент в системе будет: создание дома администратором из игры, естественно команды "войти" и "выйти" из дому, "закрыть", "открыть" дом; Для администрации - создание домов, управление замком (открыть / закрыть). Так же, 1 игрок может владеть неограниченным количеством домов! Хотелось бы отметить, если замок дома закрыт, то зайти в дом сможет только его владелец, для остальных будет высвечиваться сообщение. 

- Скриншоты системы:

Скрытый текст [Показать]



Шаг 1

 Начнем с установки библиотек и плагина:

- mxINI: после того как вы его скачали, поместите файл mxINI.inc в "pawno>include"
- sscanf: откройте архив, в нем вы увидите 2 папки "pawno" и "plugins". Папку plugins поместите в директорию с вашим сервером, из папки "pawno>include" возьмите файл sscanf2.inc и поместите туда же куда поместили ранее mxINI ("pawno>include").
Теперь вам осталось прописать в файле server.cfg напротив строки plugins > sscanf, получится вот так (если у вас нет строки plugins то просто скопируйте то, что ниже): 

Цитата

plugins sscanf


Остается последнее : открываем наш мод путем pawno>pawno.exe и вверху (можно после #include <a_samp>) подключаем библиотеки:
 

#include <mxINI>
#include <sscanf2>


Вот и все, переходим к следующему шагу.

Шаг 2

 Ко всем вашим макросам (define's) добавим еще парочку:
 

#define MAX_HOUSES 50 // Этот будет отвечать за максимально кол-во домов
#define D_H_CREATE_DESC 1 // Этот за диалог создание дома (Шаг 1)
#define D_H_CREATE_PRICE 2 // Диалог создание дома (Шаг 2)
#define D_H_CREATE_INT 3 // Диалог создание дома (Шаг 3)
#define D_H_CREATE_CONF 4 // Диалог создание дома (Подтверждение)



Макросы используются для удобства, мы можем обойтись и без них, но я привык писать названия нежели чем запоминать id (в нашем случаи диалогов).

Шаг 3

 Теперь перейдем к создаю массивов и массивов переменных для хранения наших данных. Итак, создадим массив переменных для хранения данных наших домов:
 

enum hInfo
{
        hDesc[32], // Данный массив будет использования для хранения описания дома
        hOwner[MAX_PLAYER_NAME], // Этот для хранения имени владельца
        Float:hX,Float:hY,Float:hZ, // Координаты входа в дом (x,y,z)
        hInterior, // Храним ПОРЯДКОВЫЙ ид интерьера дома (об этом я расскажу позже)
        hVirtWorld, // Виртуальный мир для дома (это позволяет создавать множество домов с одинаковыми интерьерами)
        hPrice, // Цена дома
        hLock, // Закрыт ли дом или нет
        hPick, // Пикап дома
        Text3D:hText // 3D текст с информацией о доме
};
new House[MAX_HOUSES][hInfo]; // Создаем 2-х мерный массив который будет обращаться к переменных enum'a. (Почему 2-х мерный - у каждого дома своя характеристика)



 Создадим 1 переменную и 1 массив:
 

new m_h; // Будет использоваться для подсчета точного количества созданных домов 
new STR[158]; // Массив, для редактирования строк (создаю 1 глобальный чтобы не создавать в каждой функции свой)



 Теперь создадим еще один массив переменных но уже для хранения данных интерьеров (ниже расскажу в чем суть):
 

enum hiInfo
{
        Float:hiX,Float:hiY,Float:hiZ,hiInt, // Позиции интерьера x,y,z и его id
        hiName[15], // название интерьера
}
new HInts[][hiInfo]={ // 2-х мерный массив + в нем мы сразу храним информацию об интерьерах, как вы видите, по порядку: координаты x,y,z,id интерьера,"Название"
        {318.564971,1118.209960,1083.882812,5,"Crack den"},
        {2269.4453,-1210.2952,1047.5625,10,"Hashbury House"},
        {2496.2676,-1693.8955,1014.7422,3,"Johnsons House"},
        {1299.14,-794.77,1084.00,5,"Madd Doggs M."},
        {2260.3711,-1135.7345,1050.6328,10,"R.B.M. Room"},
        {2365.6023,-1133.6688,1050.8750,8,"V. B. House"},
        {1302.519897,-1.787510,1001.028259,18,"Warehouse 2"},
        {2324.419921,-1145.568359,1050.710083,12,"Un. safe house"},
        {76.632553,-301.156829,1.578125,0,"Blueberry"}
};



Для чего мы создали этот массив? В нем вы сможете хранить всевозможные интерьеры которые могут быть присвоены домам, переменная hInterior хранит не id интерьера а порядковый id интерьера в HInts, то есть:
 

{318.564971,1118.209960,1083.882812,5,"Crack den"}, // его порядковый ид = 0
{2269.4453,-1210.2952,1047.5625,10,"Hashbury House"}, // 1
{2496.2676,-1693.8955,1014.7422,3,"Johnsons House"}, // 2 и так далее



Даже правильнее будет сказать что переменная hInteriors хранит номер ячейке в который находится тот или иной интерьер. То есть в любой момент вы можете сами выбрать интерьеры по вашему вкусу и добавить их в этот массив (HInts). Тем самым мы экономим 3 переменных для внутренних позиций (hX,hY,hZ - хранят позиции дома снаружи, а для внутренних нам достаточно всего лишь одной - hInterior которая будет содержать номер ячейки массива HInts и от туда уже брать данные (ид интерьера, и внутренние координаты)).

Шаг 4

 В этом шаге мы создадим функции для дальнейшей работы:
 

Name(playerid) // Функция для проверки ника
{
        new Nm[MAX_PLAYER_NAME];
        GetPlayerName(playerid,Nm,24);
        return Nm;
}



Внимание! Если у вас уже присутствует данная функция (которая возвращает ник игрока) не добавляйте ее, просто в дальнейшем вместо Name используйте свою!
 

SaveHouseAmount() // Функция для сохранения точного кол-во домов (понадобится для создания домов)
{
    new f=ini_openFile("houses/m_h.ini"); // Открываем файл
    ini_setInteger(f,"Amount",m_h); // Записываем значение переменной m_h в ключ Amount
        return ini_closeFile(f); // Закрываем файл
}

LoadHouses()
{
        if(!fexist("houses/m_h.ini"))return print("[Ошибка] Файл houses/m_h.ini не найден"); // Проверяем наличие файла в scriptfiles/houses (если не найден, в лог сервера выдаст ошибку)
        new f=ini_openFile("houses/m_h.ini"); // открываем файл
        ini_getInteger(f,"Amount",m_h); // получаем точное значение созданных домов
        ini_closeFile(f); // закрываем этот файл
        if(!fexist("houses/houses.ini"))return print("[Ошибка] Файл houses/houses.ini не найден"); // проверяем наличие файла houses.ini в той же директории.
        f=ini_openFile("houses/houses.ini"); // открываем его
        new str[8]; // создаем небольшой массив для дальнейшего форматирования строки (ключа в файле)
        for(new h=1;h<=m_h;h++) // запускаем цикл
        {
                format(str,sizeof(str),"ID %d",h); // форматируем строку для ключа в файле
                ini_getString(f,str,STR); // получаем данные в виде строки
        sscanf(STR,"p<|>s[32]s[24]fffiiii",House[h]
[hDesc],House[h][hOwner],House[h][hX],House[
h][hY],House[h][hZ],House[h][hInterior]
,
        House[h][hVirtWorld],House[h][hPrice],House[h]
[hLock]); // распределяем данные по переменным (данные идут через символ "|", пример: Dom 1|2.612|213.132|2.321")
        if(!strcmp(House[h][hOwner],"None",true)) // Сравниваем строки если владелец дома == None значит дом не куплен (в дальнейшем при создании владелец дома будет равен None)
                {
                        House[h][hPick]=CreatePickup(1273,23,House[h][hX]
,House[h][hY],House[h][hZ],0); // Создаем пикап дома
                        format(STR,128,"[Дом продается]\nОписание: %s\nЦена: $%d",House[h][hDesc],House[h][hPrice]);
 // Форматируем строку для 3D текста
                        House[h][hText]=Create3DTextLabel(STR,0xFFFFFFFF,House[h]
[hX],House[h][hY],House[h][hZ]+0.5,10.0,0,
0); // Создаем 3D текст
                }
                else // Иначе, если владелец дома не равен None, значит дом куплен
                {
                        House[h][hPick]=CreatePickup(1239,23,House[h][hX]
,House[h][hY],House[h][hZ],0); // Создаем пикап дома (модель пикапа уже другая)
                        format(STR,128,"[Дом]\nОписание: %s\nВладелец: %s",House[h][hDesc],House[h][hOwner]); // форматируем строку
                        House[h][hText]=Create3DTextLabel(STR,0xFFFFFFFF,House[h]
[hX],House[h][hY],House[h][hZ]+0.5,10.0,0,
0); // И создаем 3D текст с информацией
                }
        }
        ini_closeFile(f); // Закрываем фай
        return printf("Loaded %d houses",m_h); // В лог чата возвращаем кол-во загруженных домов
}

 

SaveHouse(h) // Функция для сохранения данных дома в файл
{
        new f=ini_openFile("houses/houses.ini"); // открываем файл
        new str[8]; // создаем массив для форматирования строки (для ключа, как в предыдущем случае)
        format(str,8,"ID %d",h); // форматируем строку
        format(STR,sizeof(STR),"%s|%s|%f|%f|%f|%d|%d|%d|%d",House[h][
hDesc],House[h][hOwner],House[h][hX],House[
h][hY],House[h][hZ],House[h][hInterior]
,
        House[h][hVirtWorld],House[h][hPrice],House[h]
[hLock]); // снова форматируем строку (уже с информацией о доме); вот тут кстати, вы я думаю заметили, информация через "|"
        ini_setString(f,str,STR); // записываем данные
        ini_closeFile(f); // закрываем файл
        return 1;
}


UpdateHouse(h) // Эта функция для обновления дома (например при его покупке / продаже мы будем ее использовать)
{
        DestroyPickup(House[h][hPick]); // Удаляем пикап
    if(!strcmp(House[h][hOwner],"None",true)) // Опять проверяем на владельца дома, если его нет тогда:
    {
        House[h][hPick]=CreatePickup(1273,23,House[h][hX]
,House[h][hY],House[h][hZ],0); // пикап
                format(STR,128,"[Дом продается]\nОписание: %s\nЦена: $%d",House[h][hDesc],House[h][hPrice]);
 // форматируем строку
                Update3DTextLabelText(House[h][hText],0xFFFFFFFF,STR); // ОБНОВЛЯЕМ ранее созданный 3D текст (который создался при загрузке дома)
    }
    else // если есть владелец (купили дом)
    {
        House[h][hPick]=CreatePickup(1239,23,House[h][hX]
,House[h][hY],House[h][hZ],0); // пикап
                format(STR,128,"[Дом]\nОписание: %s\nВладелец: %s",House[h][hDesc],House[h][hOwner]); // форматируем строку
                Update3DTextLabelText(House[h][hText],0xFFFFFFFF,STR); // обновляем 3D текст
    }
}



Итоги

 В этой части урока мы:

- Подключили необходимые для нас библиотеки (+плагин);
- Создали массивы для хранения различных данных;
- Создали необходимые функции которые будем использовать в дальнейшем;

Хочу отметить, при компилировании скрипта возможны варнинги, так как мы не использовали некоторые функции, на это вы пока что не обращайте внимания! Ожидайте 2-го урока, скоро! Если возникают какие-либо вопросы, пишите в данную тему. Спасибо за внимание!

 

Копирование на посторонние ресурсы запрещено! © PAWNO-RUS

 

Автор: Mike™

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!


Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.


Войти

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу