Форум Pawn-Wiki.Ru - Воплоти мечту в реальность!: Пишем систему домов с 0 [Часть 1] - Форум Pawn-Wiki.Ru - Воплоти мечту в реальность!

Перейти к содержимому

  • (6 Страниц) +
  • 1
  • 2
  • 3
  • Последняя »
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

[ Урок ]
Пишем систему домов с 0 [Часть 1] Простая система домов для игровых режимов с 0 (new.pwn)
Оценка: ***** 3 Голосов

#1
Пользователь офлайн   Mike 

  • Администратор
  • Вставить ник
  • Цитировать
  • Раскрыть информацию
Изображение

Начало
Приветствую уважаемые пользователи pawn-wiki.ru! Пока у меня есть свободное время, я решил написать урок который будет состоять из нескольких частей. В данном уроке я постараюсь как можно "раскрыто" показать вам как можно написать систему домов для игрового режима с 0 (или для "new.pwn"). Хочу отметить, что для корректной работы системы нам понадобятся 2 библиотеки:
- mxINI: Скачать
- sscanf: 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-го урока, скоро! Если возникают какие-либо вопросы, пишите в данную тему. Спасибо за внимание!

>>> Часть 2 <<<

Автор: Mike™

Копирование на посторонние ресурсы запрещено! © pawn-wiki.ru
12

#2
Пользователь офлайн   Crystal-cave 

  • Прохожий
  • Вставить ник
  • Цитировать
  • Раскрыть информацию
В public OnGameModeInit вставляем строку:
LoadHouses();


Чтобы при запуске мода загружались дома.
1

#3
Пользователь офлайн   Mike 

  • Администратор
  • Вставить ник
  • Цитировать
  • Раскрыть информацию

Просмотр сообщенияCrystal-cave (21 Апрель 2013 - 23:36) писал:

В public OnGameModeInit вставляем строку:
LoadHouses();


Чтобы при запуске мода загружались дома.


Спасибо, писал на скорую руку, вот и забыл. Добавил во 2-ю часть.
0

#4
Пользователь офлайн   !leo 

  • Знаток
  • Вставить ник
  • Цитировать
  • Раскрыть информацию
Полезный урок.

#5
Пользователь офлайн   VetalOK 

  • Брат за брата
  • Вставить ник
  • Цитировать
  • Раскрыть информацию
Mike, моё мнение такое!
Вот ты буквально пишешь динамическую систему домов! ( Ну для опытный это не проблема ).
Так вот... я считаю, что именно в уроках новичек хоть что-то может понять. ( А не тупо в готовые решения )
Я вот тоже пишу свою мод и делал на днях динам. сис. домов, а брату скинул, а он не понял нифига :steep:
Мой итог:
+ меньше нубов в Pawno :happy:
- нету..
Ну и +
0

#6
Пользователь офлайн   SaTiCH 

  • Местный
  • Вставить ник
  • Цитировать
  • Раскрыть информацию
Система хорошая.
+ заслуживает :)
0

#7
Пользователь офлайн   Tyson™ 

  • Новичок
  • Вставить ник
  • Цитировать
  • Раскрыть информацию
куда это вставлять? : Name(playerid) // Функция для проверки ника
{
new Nm[MAX_PLAYER_NAME];
GetPlayerName(playerid,Nm,24);
return Nm;
}
0

#8
Пользователь офлайн   VistigoN 

  • I Love Dub Step
  • Вставить ник
  • Цитировать
  • Раскрыть информацию

Просмотр сообщенияTyson™ (02 Май 2013 - 09:11) писал:

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


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

0

#9
Пользователь офлайн   Mike 

  • Администратор
  • Вставить ник
  • Цитировать
  • Раскрыть информацию

Просмотр сообщенияTyson™ (02 Май 2013 - 09:11) писал:

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


В любое место, можешь в конец мода.

Цитата

попробуй в stock >


В этом случае не нужно.
0

#10
Пользователь офлайн   !leo 

  • Знаток
  • Вставить ник
  • Цитировать
  • Раскрыть информацию

Просмотр сообщенияTyson™ (02 Май 2013 - 09:11) писал:

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

в stock > попробуй

Поделиться темой:


  • (6 Страниц) +
  • 1
  • 2
  • 3
  • Последняя »
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

2 человек читают эту тему
0 пользователей, 2 гостей, 0 скрытых пользователей