Доступ к готовым решениям

Переход в группу "Пользователь"

300.00
Одноразовый платёж
Быстрый переход в группу "Пользователи", без надобности написания постов и ожидания.

Покупка дает возможность:
Быть полноправным участником форума
Нормальное копирование кода
Создавать темы
Скачивать файлы
Доступ к архиву Pawno-Info

Урок Создание динамической системы домов на основе плагина [MySQL R41]

Алексей Мещеряков

Эксперт
Пользователь
Регистрация
25 Дек 2011
Сообщения
1,811
Лучшие ответы
0
Репутация
439
Здравствуйте, уважаемые читатели, гости, пользователи портала.
Как и обещал, из принципа создать какой-нибудь урок. В данном уроке, я попытаюсь объяснить, рассказать и показать, как создать динамическую систему домов на основе плагина MySQL R41.
Все мы с вами люди не доисторические, по этому будем идти в ногу со временем. На момент создания данного урока, последней версией был MySQL R41-2. Именно его мы и будем использовать.
ВАЖНО! Перед тем как создавать данную систему, желательно создать систему Регистрации, т.к. мы будем обращаться к Нику игроку через массив, который записан в таблице 'accounts'
Ну что, поехали.​

[HR][/HR]
Первое, с чего хотелось бы конечно начать - это подключение плагинов.

Плагин MySQL от pBlueG:

GitHub

1. Переходим по ссылке, указанной выше и скачиваем необходимую для вас версию MySQL.
2. Разархивируйте данный архив и все файлы которые имеются, переместите в папку с сервером.
3.Подключаем данный плагин. Заходим в server.cfg
  • В строке plugins прописываем mysql.
  • Если у вас нет строки plugins, то в самом конце, пропишите самостоятельно.
Так же, некоторое уточнение, если сервер на Linux или CentOS, необходимо дописать расширение .so(mysql.so), на Windows ничего дописывать не нужно.
4.Теперь нам необходимо подключить инклюд MySQL. Открываем наш скрипт .pwn и прописываем после #include <a_samp>, #include <a_mysql>

Плагин MySQL мы подключили, теперь подключим DC_CMD. Подключаем его сразу, по сколько команды, которые будут у нас, я буду создавать на данном командном процессоре.​
[HR][/HR]

Плагин DC_CMD от Daniel_Cortez:​

Yadi.sk
1.Переходим по ссылке указанной выше и нажимаем скачать.
2.Разархивируйте данный архив и переместите файлы в папку с вашим сервером.
3.Подключаем плагин. Заходим в server.cfg и прописываем dc_cmd (Если Linux или CentOS .so)
4.Последний шаг, это подключение инклюда. Открываем скрипт .pwn через наш редактор и после #include <a_mysql> прописываем #include <dc_cmd>
Вот мы и подключили наш второй плагин DC_CMD. Подключим еще один, это sscanf​
[HR][/HR]

Плагин sscanf от Y_Less​
GitHub

1. Переходим по ссылке, указанной выше и скачиваем необходимую для версию sscanf.
2. Разархивируйте данный архив и все файлы которые имеются, переместите в папку с сервером.
3.Подключаем плагин. Заходим в server.cfg и прописываем sscanf
4.Открываем скрипт .pwn через наш редактор и после #include <dc_cmd> прописываем #include <sscanf2>
Все плагины у нас подключены.​
[HR][/HR]

База данных.

Про то, как пользоваться Базой данной и как к ней подключиться, я долго время не буду заострять. Если желаете прочитать подробную информацию, можно найти урок от DeimoS по "Созданию системы регистрации на основе плагина MySQL [R39/R40]", там все подробно расписано. Но все же, некоторые нюансы хотелось бы уточнить.​


ПЕРВОЕ:

Как мы с вами уже знаем, а кто не знает, для работы с Базой данных(БД), нам необходимо использовать программу. Я использую Denwer.
P.S. Честно, скажу от себя, другие никогда не использовал и понятия не имею как с ними работать.

О данной программе вы можете ознакомиться на официальном сайте. |

ВТОРОЕ:

Необходимо скачать данное приложение (У кого есть, тому конечно же не нужно.)
После того, как все действия по установке данной программы выполнены, необходимо запустить "Start Denwer.exe | Run.exe".
Открываем любой для вас удобный браузер и вводите localhost.
Появляется окно:
После этого, опускаемся до таблицы, где указаны URL и Описание.
Нажимаем на 7 строку. "http://localhost/Tools/phpMyAdmin/" и переходим в Панель, откуда вы сможете управлять вашей Базой данный.

ТРЕТЬЕ:

Если у вас уже есть База Данных, то вам не нужно ничего создавать, если же у вас ее нет, то создадим сейчас.
Нажимаете на вкладку "Базы данных"
В поле "Создать базу данных" пишем название нашей БД. У меня будет pawno-info. В поле сравнение, выбираем "utf8_general_ci".
Если вы сделали все правильно, то нажимаете "Создать" и слева в колонке, должна появиться ваша База данных.
[HR][/HR]

Создание системы(таблицы) домов.​

Для начала нам необходимо выбрать нашу базу данных, в которой и будет создаваться наша система.
Как только вы выбрали вашу базу данных, на открывшейся странице появится окно с созданием таблицы, в поле "Имя" пишем название нашей таблицы - "house", в поле "Количество столбцов" - "17". В итоге у вас должно быть так:
После этого, нажимаем ОК. Идет Загрузка....После чего у вас откроется еще одно окно:
Внимание!Если вы указываете другие имена столбцов, не так, как это сделал я, то вам необходимо изменять данные и в дальнейшем.
Хранит в себе ID нашего дома.

Имя: id
Тип: INT
Длина/значения: 4
Хранит в себе Имя владельца дома.

Имя: owner
Тип: VARCHAR
Длина/значения: 24
Хранит в себе информацию о том, занят ли дом или нет.

Имя: owned
Тип: INT
Длина/значения: 2
Хранят в себе информацию о координатах входа в дом.

4 Столбец:

Имя: enter_pos_x
Тип: FLOAT

5 Столбец:

Имя: enter_pos_y
Тип: FLOAT

6 Столбец:

Имя: enter_pos_z
Тип: FLOAT
Хранят в себе информацию о координатах выхода из дома.

7 Столбец:

Имя: exit_pos_x
Тип: FLOAT

8 Столбец:

Имя: exit_pos_y
Тип: FLOAT

9 Столбец:

Имя: exit_pos_z
Тип: FLOAT
Хранит в себе информацию о цене дома.

Имя: price
Тип: INT
Длина/значения: 15
Хранит в себе информацию об уровне дома.

Имя: level
Тип: INT
Длина/значения: 4
Хранит в себе информацию о ID интерьера.

Имя: interior
Тип: INT
Длина/значения: 3
Хранят в себе информацию о координатах домашнего автомобиля.

13 Столбец:

Имя: car_pos_x
Тип: FLOAT

14 Столбец:

Имя: car_pos_y
Тип: FLOAT

15 Столбец:

Имя: car_pos_z
Тип: FLOAT

16 Столбец:

Имя: car_pos_angle
Тип: FLOAT
Хранит в себе ID домашнего автомобиля.

Имя: vehicle
Тип: INT
Длина/значения: 4
После того как все поля были успешно заполнены, нажимаем "Сохранить", после этого ваша таблица будет успешно сохранена и появится слева в вашей Базе данных.
[HR][/HR]

Подключение к Базе данных.

1. Открываем наш скрипт .pwn и после подключенных инклюдов, именно строчки #include <dc_cmd>, добавляем подключение:
!!!Если у кого то, уже имеется БД и подключение, повторного не нужно создавать(или вводите свои данные от БД)
2. Добавим переменную, в которой будет храниться ID нашего подключения.
PHP:
new MySQL:mysql_connect_ID;
3. Подключение к базе данных. В OnGameModeInit прописываем следующий код.
PHP:
mysql_connect_ID = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE);
[HR][/HR]

Хранение данных в энуменаторе(enum)​

Под нашу переменную подключения, добавим следующий код.
PHP:
enum e_house_information
{
	hID,
    hOwner[MAX_PLAYER_NAME],
    hOwned,
    Float:henter_pos_x,
    Float:henter_pos_y,
    Float:henter_pos_z,
    Float:hexit_pos_x,
    Float:hexit_pos_y,
    Float:hexit_pos_z,
    hPrice,
    Text3D: hText,
    hPickup,
    hMapicon,
    hLevel,
    hInt,
    Float:hcar_pos_x,
    Float:hcar_pos_y,
    Float:hcar_pos_z,
    Float:hcar_pos_angle,
    hHouse_Car
};

const MAX_HOUSE = 1000;

new HouseInfo[MAX_HOUSE][e_house_information];
new HouseCar[MAX_HOUSE];

new TOTALHOUSE;
new homelevel[MAX_PLAYERS];
new homeprice[MAX_PLAYERS];
В нашем перечислении(enum), мы создали члены перечисления, в которых будет храниться разная информация о нашем доме.
Из названия наших ячеек, можно понять, что за что у нас отвечает, но все же поясню.
PHP:
hID, // ID нашего дома
hOwner[MAX_PLAYER_NAME], // Имя владельца дома
hOwned, // Проверка на владельца дома
Float:henter_pos_x, // Координата входа в дом X
Float:henter_pos_y, // Координата входа в дом Y
Float:henter_pos_z, // Координата входа в дом Z
Float:hexit_pos_x, // Координата выхода из дома X
Float:hexit_pos_y, // Координата выхода из дома Y
Float:hexit_pos_z, // Координата выхода из дома Z
hPrice, // Цена дома
Text3D: hText, // 3D Текст об информации нашего дома
hPickup, // Пикап возле дома
hMapicon, // Иконка дома на карте
hLevel, // Уровень дома
hInt, // Интерьер дома
Float:hcar_pos_x, // Координата машины X
Float:hcar_pos_y, // Координата машины Y
Float:hcar_pos_z, // Координата машины Z
Float:hcar_pos_angle, // Угол поворота машины
hHouse_Car // ID машины
PHP:
const MAX_HOUSE = 1000;
Создание константы.
const - это константа, значение которой вы устанавливаете сами и оно не измениться не при каких условиях, мы ее приравняли к 1000, т.е. максимальное количество домов у нас 1000.
Для удобства, чтобы не искать во всем моде где изменить значение домов, вы указываете в данной константе нужное вам количество.
PHP:
new HouseInfo[MAX_HOUSE][e_house_information];
Мы создали массив, через который мы будем обращаться всякий раз к нужной ячейке нашего перечисления.
[MAX_HOUSE] Указано как максимальное количество домов.
[e_house_information] - Это массив с выводом данных из нашего перечисления.
PHP:
new HouseCar[MAX_HOUSE];
Это массив в котором хранятся ID наших авто.
PHP:
new TOTALHOUSE;
Переменная, в которой хранится общее количество домов, на нашем сервере.
PHP:
new homelevel[MAX_PLAYERS];
Переменная, в которой хранится уровень дома, на время создания.
PHP:
new homeprice[MAX_PLAYERS];
Переменная, в которой хранится стоимость дома, на время создания.

Энуменатор с информацией дома у нас добавлен. Теперь добавив enum с информацией интерьера.
После наших переменных добавим следующий код:
PHP:
const MAX_INTERIOR_NAME = 12;
const MAX_HOUSE_INTERIOR = 34;

enum e_HOUSE_INTERIORS_INFO
{
    h_int_name[MAX_INTERIOR_NAME],
    Float:h_int_pos_x,
    Float:h_int_pos_y,
    Float:h_int_pos_z,
    h_int_interiorid
};

new hInteriorInfo[MAX_HOUSE_INTERIOR][e_HOUSE_INTERIORS_INFO] =
{
    {"Интерьер 1", 235.508994, 1189.169897, 1080.339966, 3},
    {"Интерьер 2", 225.756989, 1240.000000, 1082.149902, 2},
    {"Интерьер 3", 223.043991, 1289.259888, 1082.199951, 1},
    {"Интерьер 4", 225.630997, 1022.479980, 1084.069946, 7},
    {"Интерьер 5", 295.138977, 1474.469971, 1080.519897, 15},
    {"Интерьер 6", 328.493988, 1480.589966, 1084.449951, 15},
    {"Интерьер 7", 386.8652, 1471.8932, 1080.1875, 15},
    {"Интерьер 8", 2214.4895, -1150.5736, 1025.7969, 15},
    {"Интерьер 9", 2451.77, -1699.80, 1013.51, 2},
    {"Интерьер 10", 2251.85, -1138.16, 1050.63, 9},
    {"Интерьер 11", 2260.76, -1210.45, 1049.02, 10},
    {"Интерьер 12", 2495.9, -1692.63, 1014.74, 3},
    {"Интерьер 13", 1299.14, -794.77, 1084.00, 5},
    {"Интерьер 14", 2262.83, -1137.71, 1050.63, 10},
    {"Интерьер 15", 2365.42, -1131.85, 1050.88, 8},
    {"Интерьер 16", 2324.4260, -1148.7495, 1050.71, 12},
    {"Интерьер 17", 2233.6919, -1112.8107, 1050.8828, 5},
    {"Интерьер 18", 2319.1272, -1023.9562, 1050.2109, 9},
    {"Интерьер 19", 239.2819, 1114.1991, 1080.9922, 5},
    {"Интерьер 20", 446.3247, 509.9662, 1001.419, 12},
    {"Интерьер 21", 446.626, 1397.738, 1084.3047, 2},
    {"Интерьер 22", 261.1165, 1287.2197, 1080.2578, 4},
    {"Интерьер 23", 306.1966, 307.819, 1003.3047, 4},
    {"Интерьер 24", 24.3769, 1341.1829, 1084.375, 10},
    {"Интерьер 25", 221.6766, 1142.4962, 1082.6094, 4},
    {"Интерьер 26", -262.1759, 1456.6158, 1084.3672, 4},
    {"Интерьер 27", 234.2826, 1065.229, 1084.2101, 6},
    {"Интерьер 28", -68.5145, 1353.8485, 1080.2109, 6},
    {"Интерьер 29", -285.2511, 1471.197, 1084.375, 15},
    {"Интерьер 30", -42.5267, 1408.23, 1084.4297, 8},
    {"Интерьер 31", 84.9244, 1324.2983, 1083.8594, 9},
    {"Интерьер 32", 22.7322, 1404.7037, 1084.4297, 5},
    {"Интерьер 33", 244.6048, 304.8997, 999.1484, 1},
    {"Интерьер 34", 140.2324, 1366.1829, 1083.8621, 5}
};

new house_interior_list[MAX_HOUSE_INTERIOR*MAX_INTERIOR_NAME+1];
PHP:
const MAX_INTERIOR_NAME = 12; 
const MAX_HOUSE_INTERIOR = 34; 

enum e_HOUSE_INTERIORS_INFO 
{ 
    h_int_name[MAX_INTERIOR_NAME], 
    Float:h_int_pos_x, 
    Float:h_int_pos_y, 
    Float:h_int_pos_z, 
    h_int_interiorid 
};
const MAX_INTERIOR_NAME - Отвечает за количество символов в названии нашего Интерьера.(Если будете изменять названия, то изменяйте и константу)
const MAX_HOUSE_INTERIOR - Отвечает за количество интерьеров. В данном случае я добавил 34, вроде все, а может и нет. Будете добавлять, не забывайте увеличивать константу.

В enum e_HOUSE_INTERIORS_INFO внесена вся информация о нашем интерьере, для удобного дальнейшего использования.

h_int_name[MAX_INTERIOR_NAME] - Наименование нашего интерьера, с размером const MAX_INTERIOR_NAME.
Float:h_int_pos_x - Координата интерьера X.
Float:h_int_pos_y - Координата интерьера Y.
Float:h_int_pos_z - Координата интерьера Z.
h_int_interiorid - ID интерьера.
PHP:
new hInteriorInfo[MAX_HOUSE_INTERIOR][e_HOUSE_INTERIORS_INFO] =
{
    {"Интерьер 1", 235.508994, 1189.169897, 1080.339966, 3},
    {"Интерьер 2", 225.756989, 1240.000000, 1082.149902, 2},
    {"Интерьер 3", 223.043991, 1289.259888, 1082.199951, 1},
    {"Интерьер 4", 225.630997, 1022.479980, 1084.069946, 7},
    {"Интерьер 5", 295.138977, 1474.469971, 1080.519897, 15},
    {"Интерьер 6", 328.493988, 1480.589966, 1084.449951, 15},
    {"Интерьер 7", 386.8652, 1471.8932, 1080.1875, 15},
    {"Интерьер 8", 2214.4895, -1150.5736, 1025.7969, 15},
    {"Интерьер 9", 2451.77, -1699.80, 1013.51, 2},
    {"Интерьер 10", 2251.85, -1138.16, 1050.63, 9},
    {"Интерьер 11", 2260.76, -1210.45, 1049.02, 10},
    {"Интерьер 12", 2495.9, -1692.63, 1014.74, 3},
    {"Интерьер 13", 1299.14, -794.77, 1084.00, 5},
    {"Интерьер 14", 2262.83, -1137.71, 1050.63, 10},
    {"Интерьер 15", 2365.42, -1131.85, 1050.88, 8},
    {"Интерьер 16", 2324.4260, -1148.7495, 1050.71, 12},
    {"Интерьер 17", 2233.6919, -1112.8107, 1050.8828, 5},
    {"Интерьер 18", 2319.1272, -1023.9562, 1050.2109, 9},
    {"Интерьер 19", 239.2819, 1114.1991, 1080.9922, 5},
    {"Интерьер 20", 446.3247, 509.9662, 1001.419, 12},
    {"Интерьер 21", 446.626, 1397.738, 1084.3047, 2},
    {"Интерьер 22", 261.1165, 1287.2197, 1080.2578, 4},
    {"Интерьер 23", 306.1966, 307.819, 1003.3047, 4},
    {"Интерьер 24", 24.3769, 1341.1829, 1084.375, 10},
    {"Интерьер 25", 221.6766, 1142.4962, 1082.6094, 4},
    {"Интерьер 26", -262.1759, 1456.6158, 1084.3672, 4},
    {"Интерьер 27", 234.2826, 1065.229, 1084.2101, 6},
    {"Интерьер 28", -68.5145, 1353.8485, 1080.2109, 6},
    {"Интерьер 29", -285.2511, 1471.197, 1084.375, 15},
    {"Интерьер 30", -42.5267, 1408.23, 1084.4297, 8},
    {"Интерьер 31", 84.9244, 1324.2983, 1083.8594, 9},
    {"Интерьер 32", 22.7322, 1404.7037, 1084.4297, 5},
    {"Интерьер 33", 244.6048, 304.8997, 999.1484, 1},
    {"Интерьер 34", 140.2324, 1366.1829, 1083.8621, 5}
};
Сам массив, представляет собой(в нашем случае) 34 строки | 5 столбцов, где каждый параметр массива, относится к ячейке энуменатора.
PHP:
new house_interior_list[MAX_HOUSE_INTERIOR*MAX_INTERIOR_NAME+1];
Объявив данную переменную, мы всякий раз будем обращаться к названию наших интерьеров, чтобы не объявлять массив повторно с их названием, а просто извлекаем из него необходимые данные
Так же в public OnGameModeInit добавим цикл на проверку всех наших интерьеров:
PHP:
for(new i; i < MAX_HOUSE_INTERIOR; i++)
{
    format(house_interior_list, sizeof(house_interior_list), "%s%s\n", house_interior_list, hInteriorInfo[i][h_int_name]);
}
Через цикл, мы делаем перебор всех наших интерьеров. Необходимо только менять значение const MAX_HOUSE_INTERIOR.
Теперь все названия интерьеров (hInteriorInfo[h_int_name]) будут храниться в house_interior_list и нам не придется каждый раз писать названия Интерьеров.

[HR][/HR]

Макросы:​

Для упрощения работы с диалогами, добавим макросы:
PHP:
#define dHouse_Price			0
#define dHouse_Level			1
#define dHouse_Int			  2
#define dHouse_Veh			  3
P.S. Вы можете менять на свои ID, если же у вас есть enum с перечислением ID диалогов(что еще лучше) используйте его.
[HR][/HR]

Команды создания:​

Итак, начнем с первой команды по созданию дома.
Я назову ее /addhouse(Вы можете любую другую). Т.к. мод у нас new.pwn то дополнительные проверки создавать не буду.
Добавляем следующий код в любое для вас удобное место:
PHP:
CMD:addhouse(playerid, params[])
{
	ShowPlayerDialog(playerid, dHouse_Price, DIALOG_STYLE_INPUT, "Создание дома", "Укажите стоимость создаваемого дома", "Далее", "Отмена");
	return 1;
}
Первая команда у нас будет отвечать, непосредственно, за стоимость нашего дома.
Создаем первый диалог Где dHouse_Price - ID диалога. Если данный ID занят, меняйте на свой.
Вторая наша команда:
PHP:
CMD:addcar(playerid, params[])
{
	if(!IsPlayerInAnyVehicle(playerid))
		return SendClientMessage(playerid, -1, "Вы должны быть в автомобиле!");

	ShowPlayerDialog(playerid, dHouse_Veh, DIALOG_STYLE_INPUT, "Создание авто", "Установите авто в нужном месте и укажите номер дома для прикрепления к нему транспорта.", "Ок", "Отмена");
	return true;
}
Эта команда служит для создания авто, к нашему дому.
Так же, мы установили проверку IsPlayerInAnyVehicle, чтобы знать, находится ли игрок в машине или нет.
На этом, пока что необходимые нам команды мы создали.
[HR][/HR]

Диалоги​

Итак, перейдем непосредственно в public OnDialogResponse и добавим наш код по первому диалогу.
PHP:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
	switch(dialogid)
	{
		case dHouse_Price:
		{
			if(!response) return 1;
			if(!strlen(inputtext))
			{
			    SendClientMessage(playerid, -1, "Ошибка введите стоимость дома.");
			    ShowCreateHouseMenu_Price(playerid);
			    return 1;
			}
			homeprice[playerid] = strval(inputtext);
			ShowPlayerDialog(playerid, dHouse_Level, DIALOG_STYLE_INPUT, "Создание дома", "Укажите уровень создаваемого дома", "Далее", "Отмена");
		}
	}
	return 1;
}
Итак, давайте посмотрим, что мы сделали.
PHP:
if(!strlen(inputtext))
С помощью функции strlen мы узнаем длину текста, который ввели в нашем диалоге. Если мы не ввели никакого текста и нажали на кнопку "Далее", то вам отобразится диалог заново.
PHP:
ShowCreateHouseMenu_Price(playerid);
Эту функцию мы добавим чуть позже, сделано чтобы не изменять текст в одинаковых диалогах, мы его создадим один раз.
PHP:
homeprice[playerid] = strval(inputtext);
При успешной записи мы сохраняем наш текст в численном в виде, благодаря функции strval в переменную homeprice, после чего показываем наш следующий диалог по созданию дома.
Добавим после данного диалога, на второй диалог:
PHP:
case dHouse_Level:
		{
		    if(!response) return 1;
			if(!strlen(inputtext))
			{
			    SendClientMessage(playerid, -1, "Ошибка введите уровень дома.");
			    ShowCreateHouseMenu_Level(playerid);
			    return 1;
			}
			homelevel[playerid] = strval(inputtext);
			ShowPlayerDialog(playerid, dHouse_Int, DIALOG_STYLE_LIST, "Укажите интерьер", house_interior_list, "Выбрать", "Отмена");
		}
Тут мы аналогично с первым диалог, сделали сохранение нашего целочисленного текста в переменную homelevel.
Так же добавили в наш диалог информацию об интерьерах. С помощью house_interior_list мы выводим только текст, а не создаем еще один большой массив.
Добавим наш последний диалог по созданию дома, с выбором интерьера. Сразу скажу, старался добавить интерьеры по максимуму, какие только нашел.
PHP:
		case dHouse_Int:
        {
            if(response)
            {
                new Float: player_pos_x,
                    Float: player_pos_y,
                    Float: player_pos_z,
                    Float: exit_pos_x,
                    Float: exit_pos_y,
                    Float: exit_pos_z,
                    string[600],
                    inter;

                inter = hInteriorInfo[listitem][h_int_interiorid];
                exit_pos_x = hInteriorInfo[listitem][h_int_pos_x];
                exit_pos_y = hInteriorInfo[listitem][h_int_pos_y];
                exit_pos_z = hInteriorInfo[listitem][h_int_pos_z];

                TOTALHOUSE++;

                GetPlayerPos(playerid, player_pos_x, player_pos_y, player_pos_z);
                format(string, sizeof string,"INSERT INTO `house`(`id`,`owner`,`owned`,`enter_pos_x`,`enter_pos_y`,`enter_pos_z`,`exit_pos_x`,`exit_pos_y`,`exit_pos_z`, `price`, `level`, `interior`)\
                                         VALUES ('%d','None','0','%f','%f','%f','%f','%f','%f','%d','%d','%d')",
                                         TOTALHOUSE, player_pos_x, player_pos_y, player_pos_z, exit_pos_x, exit_pos_y, exit_pos_z, homeprice[playerid], homelevel[playerid], inter);

                mysql_tquery(mysql_connect_ID, string, "", "");
                strcat(HouseInfo[TOTALHOUSE][hOwner], "None");
                HouseInfo[TOTALHOUSE][hID] = TOTALHOUSE;
                HouseInfo[TOTALHOUSE][hOwned] = 0;
                HouseInfo[TOTALHOUSE][henter_pos_x] = player_pos_x;
                HouseInfo[TOTALHOUSE][henter_pos_y] = player_pos_y;
                HouseInfo[TOTALHOUSE][henter_pos_z] = player_pos_z;
                HouseInfo[TOTALHOUSE][hexit_pos_x] = exit_pos_x;
                HouseInfo[TOTALHOUSE][hexit_pos_y] = exit_pos_y;
                HouseInfo[TOTALHOUSE][hexit_pos_z] = exit_pos_z;
                HouseInfo[TOTALHOUSE][hPrice] = homeprice[playerid];
                HouseInfo[TOTALHOUSE][hLevel] = homelevel[playerid];
                HouseInfo[TOTALHOUSE][hInt] = inter;

                static const fmt_str[] = "{FFDEAD}ID: {FFFFFF}[%d]\n{FFDEAD}Владелец: {FFFFFF}Нет\n{FFDEAD}Стоимость: {FFFFFF}$%d\n{FFDEAD}Уровень: {FFFFFF}%d";
                new str[sizeof(fmt_str) + ((3-2) + (10-2) + (20-2) + (3-2))];

                format(str, sizeof(str), fmt_str, HouseInfo[TOTALHOUSE][hID], HouseInfo[TOTALHOUSE][hPrice], HouseInfo[TOTALHOUSE][hLevel]);
                HouseInfo[TOTALHOUSE][hText] = Create3DTextLabel(str, 0xFFFFFFFF, HouseInfo[TOTALHOUSE][henter_pos_x], HouseInfo[TOTALHOUSE][henter_pos_y], HouseInfo[TOTALHOUSE][henter_pos_z], 7,0,1);
                HouseInfo[TOTALHOUSE][hPickup] = CreatePickup(1273, 1, HouseInfo[TOTALHOUSE][henter_pos_x], HouseInfo[TOTALHOUSE][henter_pos_y], HouseInfo[TOTALHOUSE][henter_pos_z], -1);
                HouseInfo[TOTALHOUSE][hMapicon] = SetPlayerMapIcon(playerid, 12, HouseInfo[TOTALHOUSE][henter_pos_x], HouseInfo[TOTALHOUSE][henter_pos_y], HouseInfo[TOTALHOUSE][henter_pos_z], 31, -1, MAPICON_LOCAL);
            }
            else{}
        }
Что же, давайте разберем с вами столь немаленький код.
Начнем с первого, это переменные, которые мы объявили.
PHP:
new Float: player_pos_x,
	Float: player_pos_y,
	Float: player_pos_z,
	Float: exit_pos_x,
	Float: exit_pos_y,
	Float: exit_pos_z,
	string[600],
	inter;
Первый ряд переменных был создан для записи позиции игрока, где будет создан дом, это соответственно:
PHP:
Float: player_pos_x, // Позиция игрока по X
Float: player_pos_y, // Позиция игрока по Y
Float: player_pos_z, // Позиция игрока по Z
Если немного забежать вперед, то при создании и записи данных в БД мы увидим функцию.
PHP:
GetPlayerPos(playerid, player_pos_x, player_pos_y, player_pos_z);
Как раз в эти данные мы записали и получили позицию игрока.

Дальше были созданы переменные, которые отвечают за координаты и ID интерьера:
PHP:
Float: exit_pos_x, // Координата интерьера/выхода X
Float: exit_pos_y, // Координата интерьера/выхода Y
Float: exit_pos_z, // Координата интерьера/выхода Z
inter; // ID интерьера
С помощью данных переменных, мы можем записать значение нашего интерьера(Координаты и ID) в ячейки, отвечающие за это в нашей таблице.

И последнее - это массив.
PHP:
string[600],
Его мы используем для записи всей информации, которую сохраняем в нашу таблицу.

Информация из массива:
PHP:
inter = hInteriorInfo[listitem][h_int_interiorid];
exit_pos_x = hInteriorInfo[listitem][h_int_pos_x];
exit_pos_y = hInteriorInfo[listitem][h_int_pos_y];
exit_pos_z = hInteriorInfo[listitem][h_int_pos_z];
К переменным мы записали данные массива, которые автоматически записали нужную нам информацию.
Выше разбирали, что к чему относится.

PHP:
TOTALHOUSE++;
Данный код отвечает за Итоговое количество домов, чтобы они у нас не повторялись и не пересоздавался дом с одним ID, при каждом создании мы прибавляем 1 (+1 | ++).
PHP:
format(string, sizeof string,"INSERT INTO `house`(`owner`,`id`,`owned`,`enter_pos_x`,`enter_pos_y`,`enter_pos_z`,`exit_pos_x`,`exit_pos_y`,`exit_pos_z`, `price`, `level`, `interior`)\ 
                                         VALUES ('None','%d','0','%f','%f','%f','%f','%f','%f','%d','%d','%d')", 
                                         TOTALHOUSE,player_pos_x, player_pos_y, player_pos_z, exit_pos_x, exit_pos_y, exit_pos_z, homeprice[playerid], homelevel[playerid], inter); 

mysql_tquery(mysql_connect_ID, string, "", "");
Мы отправляем запрос через функцию mysql_tquery, где mysql_connect_ID - ID нашего подключения. После этого, данные в нашей таблице обновятся.
PHP:
HouseInfo[TOTALHOUSE][hID] = TOTALHOUSE;
HouseInfo[TOTALHOUSE][hOwned] = 0;
HouseInfo[TOTALHOUSE][henter_pos_x] = player_pos_x;
HouseInfo[TOTALHOUSE][henter_pos_y] = player_pos_y;
HouseInfo[TOTALHOUSE][henter_pos_z] = player_pos_z;
HouseInfo[TOTALHOUSE][hexit_pos_x] = exit_pos_x;
HouseInfo[TOTALHOUSE][hexit_pos_y] = exit_pos_y;
HouseInfo[TOTALHOUSE][hexit_pos_z] = exit_pos_z;
HouseInfo[TOTALHOUSE][hPrice] = homeprice[playerid];
HouseInfo[TOTALHOUSE][hLevel] = homelevel[playerid];
HouseInfo[TOTALHOUSE][hInt] = inter;
В первой группе ячеек мы указали TOTALHOUSE, дабы определить ID дома в который запишется информация.
Во второй группе мы записали данные, полученные в результате создания.
Последняя часть кода:
PHP:
static const fmt_str[] = "{FFDEAD}ID: {FFFFFF}[%d]\n{FFDEAD}Владелец: {FFFFFF}Нет\n{FFDEAD}Стоимость: {FFFFFF}$%d\n{FFDEAD}Уровень: {FFFFFF}%d"; 
new str[sizeof(fmt_str) + ((3-2) + (10-2) + (20-2) + (3-2))]; 

format(str, sizeof(str), fmt_str, HouseInfo[TOTALHOUSE][hID], HouseInfo[TOTALHOUSE][hPrice], HouseInfo[TOTALHOUSE][hLevel]); 
HouseInfo[TOTALHOUSE][hText] = Create3DTextLabel(str, 0xFFFFFFFF, HouseInfo[TOTALHOUSE][henter_pos_x], HouseInfo[TOTALHOUSE][henter_pos_y], HouseInfo[TOTALHOUSE][henter_pos_z], 7,0,1); 
HouseInfo[TOTALHOUSE][hPickup] = CreatePickup(1273, 1, HouseInfo[TOTALHOUSE][henter_pos_x], HouseInfo[TOTALHOUSE][henter_pos_y], HouseInfo[TOTALHOUSE][henter_pos_z], -1); 
HouseInfo[TOTALHOUSE][hMapicon] = SetPlayerMapIcon(playerid, 12, HouseInfo[TOTALHOUSE][henter_pos_x], HouseInfo[TOTALHOUSE][henter_pos_y], HouseInfo[TOTALHOUSE][henter_pos_z], 31, -1, MAPICON_LOCAL);
Создаем текст и делаем автоподсчет.
После чего отображается 3D текст | Пикап | Иконка по координатам входа в дом.
Остался один диалог с установкой нашего транспорта.
PHP:
		case dHouse_Veh:
        {
            if(!response) return 1;
            new house_nomer;
            if(sscanf(inputtext, "d", house_nomer))
                return ShowPlayerDialog(playerid, dHouse_Veh ,DIALOG_STYLE_INPUT,
				"Создание авто",
                "Установите авто в нужном месте и укажите номер дома для прикрепления к нему транспорта.",
                "Ок",
				"Отмена");

            if(house_nomer > TOTALHOUSE)
                return SendClientMessage(playerid,-1, "Дома с указанным вами ID не существует.");

            new Float:pos_x,
                Float:pos_y,
                Float:pos_z,
                Float:angle,
                string[200];

            GetVehiclePos(GetPlayerVehicleID(playerid), pos_x, pos_y, pos_z);
            GetVehicleZAngle(GetPlayerVehicleID(playerid), angle);

            format(string, sizeof string, "UPDATE `house` SET\
			`car_pos_x` = '%f',\
			`car_pos_y` = '%f',\
			`car_pos_z` = '%f',\
			`car_pos_angle` = '%f',\
		 	`vehicle` = '410'\
		  	WHERE `id` = '%d'",pos_x, pos_y, pos_z, angle, house_nomer);

            mysql_tquery(mysql_connect_ID, string, "", "");
            HouseInfo[house_nomer][hcar_pos_x] = pos_x;
            HouseInfo[house_nomer][hcar_pos_y] = pos_y;
            HouseInfo[house_nomer][hcar_pos_z] = pos_z;
            HouseInfo[house_nomer][hcar_pos_angle] = angle;
            HouseInfo[house_nomer][hHouse_Car] = 410;
            SendClientMessage(playerid, -1, "Теперь авто указанного вами дома будет появляться в заданном месте.");
        }
Тут мы используем все по аналогии создания дома.
С помощью функций:
PHP:
GetVehiclePos(GetPlayerVehicleID(playerid), pos_x, pos_y, pos_z);
GetVehicleZAngle(GetPlayerVehicleID(playerid), angle);
GetVehiclePos - Узнаем позицию нашей машины.
GetVehicleZAngle - Узнаем угол поворота машины.
PHP:
HouseInfo[house_nomer][hcar_pos_x] = pos_x;
HouseInfo[house_nomer][hcar_pos_y] = pos_y;
HouseInfo[house_nomer][hcar_pos_z] = pos_z;
HouseInfo[house_nomer][hcar_pos_angle] = angle;
HouseInfo[house_nomer][hHouse_Car] = 410;
В итоге, мы сделали запись наших координат, в таблицу с нашими данными.
Данные в нашу таблицу успешно записаны. Мы завершили создание дома.

В конце мода создадим две функции. Добавим следующий код:
PHP:
stock ShowCreateHouseMenu_Price(playerid)
{
	ShowPlayerDialog(playerid, dHouse_Price, DIALOG_STYLE_INPUT, "Создание дома", "Укажите стоимость создаваемого дома", "Далее", "Отмена");
	return 1;
}

stock ShowCreateHouseMenu_Level(playerid)
{
	ShowPlayerDialog(playerid, dHouse_Level, DIALOG_STYLE_INPUT, "Создание дома", "Укажите уровень создаваемого дома", "Далее", "Отмена");
	return 1;
}
Для чего были созданы stock я описывал выше.
[HR][/HR]

Загрузка домов.

Итак приступаем к важной части - это загрузка.
!!!P.s. Важно для тех, кто менял названия в таблице, будьте внимательны, указывать свои наименования.
Ну что же, добавим данный код в конец нашего мода и давайте его разберем:
PHP:
forward LoadHouse(); 
public LoadHouse()
{
    cache_get_row_count(TOTALHOUSE);
    if(TOTALHOUSE)
    {
        static const h_no_owner[] = "{FFDEAD}ID: {FFFFFF}[%d]\n{FFDEAD}Владелец: {FFFFFF}Нет\n{FFDEAD}Стоимость: {FFFFFF}%d\n{FFDEAD}Уровень: {FFFFFF}%d";
        static const h_any_owner[] = "{FFDEAD}ID: {FFFFFF}[%d]\n{FFDEAD}Владелец: {FFFFFF}%s\n{FFDEAD}Уровень: {FFFFFF}%d";

        new h_info[sizeof(h_any_owner) + ((3-2) + (24-2) + (20-2) + (5-2))];

        for(new h = 0; h < TOTALHOUSE; h++)
        {
            cache_get_value_name_int(h,"id",HouseInfo[h][hID]);
            cache_get_value_name(h,"owner",HouseInfo[h][hOwner],MAX_PLAYER_NAME);
            cache_get_value_name_int(h, "owned", HouseInfo[h][hOwned]);
            cache_get_value_name_float(h, "enter_pos_x", HouseInfo[h][henter_pos_x]);
            cache_get_value_name_float(h, "enter_pos_y", HouseInfo[h][henter_pos_y]);
            cache_get_value_name_float(h, "enter_pos_z", HouseInfo[h][henter_pos_z]);
            cache_get_value_name_float(h, "exit_pos_x", HouseInfo[h][hexit_pos_x]);
            cache_get_value_name_float(h, "exit_pos_y", HouseInfo[h][hexit_pos_y]);
            cache_get_value_name_float(h, "exit_pos_z", HouseInfo[h][hexit_pos_z]);
            cache_get_value_name_int(h, "price", HouseInfo[h][hPrice]);
            cache_get_value_name_int(h, "level", HouseInfo[h][hLevel]);
            cache_get_value_name_int(h, "interior", HouseInfo[h][hInt]);
            cache_get_value_name_float(h, "car_pos_x", HouseInfo[h][hcar_pos_x]);
            cache_get_value_name_float(h, "car_pos_y", HouseInfo[h][hcar_pos_y]);
            cache_get_value_name_float(h, "car_pos_z", HouseInfo[h][hcar_pos_z]);
            cache_get_value_name_float(h, "car_pos_angle", HouseInfo[h][hcar_pos_angle]);
            cache_get_value_name_int(h, "vehicle", HouseInfo[h][hHouse_Car]);

            if(!HouseInfo[h][hOwned])
            {
                format(h_info, sizeof(h_info), h_no_owner, HouseInfo[h][hID], HouseInfo[h][hPrice],HouseInfo[h][hLevel]);
                HouseInfo[h][hPickup] = CreatePickup(1273, 1, HouseInfo[h][henter_pos_x], HouseInfo[h][henter_pos_y], HouseInfo[h][henter_pos_z], -1);
                HouseInfo[h][hText]  = Create3DTextLabel(h_info, 0x008080FF, HouseInfo[h][henter_pos_x], HouseInfo[h][henter_pos_y], HouseInfo[h][henter_pos_z], 7, 0);
            	HouseInfo[h][hMapicon] = SetPlayerMapIcon(h, 12, HouseInfo[h][henter_pos_x], HouseInfo[h][henter_pos_y], HouseInfo[h][henter_pos_z], 31, -1, MAPICON_LOCAL);
			}
            else
            {
                format(h_info, sizeof(h_info), h_any_owner, HouseInfo[h][hID], HouseInfo[h][hOwner],HouseInfo[h][hLevel]);
                HouseInfo[h][hPickup] = CreatePickup(1272, 1, HouseInfo[h][henter_pos_x], HouseInfo[h][henter_pos_y], HouseInfo[h][henter_pos_z], -1);
                HouseInfo[h][hText]  = Create3DTextLabel(h_info, 0xFFFFFF, HouseInfo[h][henter_pos_x], HouseInfo[h][henter_pos_y], HouseInfo[h][henter_pos_z], 7.0, 0);
            }
        }
    }
    printf("[ЗАГРУЖЕНО ДОМОВ]: <%d>", TOTALHOUSE);
    return 1;
}
PHP:
cache_get_row_count(TOTALHOUSE);
Функция возвращает количество строк. Подробнее можете ознакомиться |
PHP:
static const h_no_owner[] = "{FFDEAD}ID: {FFFFFF}[%d]\n{FFDEAD}Владелец: {FFFFFF}Нет\n{FFDEAD}Стоимость: {FFFFFF}%d\n{FFDEAD}Уровень: {FFFFFF}%d";
static const h_any_owner[] = "{FFDEAD}ID: {FFFFFF}[%d]\n{FFDEAD}Владелец: {FFFFFF}%s\n{FFDEAD}Уровень: {FFFFFF}%d";

new h_info[sizeof(h_any_owner) + ((3-2) + (24-2) + (20-2) + (5-2))];
Делаем автоподсчет самой длинной строки, т.к. нет смысла объявлять дважды.
Объявлены два значения - это h_no_owner и h_any_owner. У кого плохо с англиским переведу (Нет владельца | Есть владелец)

Дальше циклом проверяем наши дома, которые созданы в базе данных.
PHP:
for(new h = 0; h < TOTALHOUSE; h++)
Описывать каждый столбец я не буду, т.к. при создании самой таблицы было подробное описание. Опишу только сами функции, которые мы используем:

| Получаем значение в виде целого числа.
| Получаем значение строки.
| Получаем значение числа с плавающей точкой.

PHP:
            if(!HouseInfo[h][hOwned])
            {
                format(h_info, sizeof(h_info), h_no_owner, HouseInfo[h][hID], HouseInfo[h][hPrice],HouseInfo[h][hLevel]);
                HouseInfo[h][hPickup] = CreatePickup(1273, 1, HouseInfo[h][henter_pos_x], HouseInfo[h][henter_pos_y], HouseInfo[h][henter_pos_z], -1);
                HouseInfo[h][hText]  = Create3DTextLabel(h_info, 0x008080FF, HouseInfo[h][henter_pos_x], HouseInfo[h][henter_pos_y], HouseInfo[h][henter_pos_z], 7, 0);
            	HouseInfo[h][hMapicon] = SetPlayerMapIcon(h, 12, HouseInfo[h][henter_pos_x], HouseInfo[h][henter_pos_y], HouseInfo[h][henter_pos_z], 31, -1, MAPICON_LOCAL);
			}
            else
            {
                format(h_info, sizeof(h_info), h_any_owner, HouseInfo[h][hID], HouseInfo[h][hOwner],HouseInfo[h][hLevel]);
                HouseInfo[h][hPickup] = CreatePickup(1272, 1, HouseInfo[h][henter_pos_x], HouseInfo[h][henter_pos_y], HouseInfo[h][henter_pos_z], -1);
                HouseInfo[h][hText]  = Create3DTextLabel(h_info, 0xFFFFFF, HouseInfo[h][henter_pos_x], HouseInfo[h][henter_pos_y], HouseInfo[h][henter_pos_z], 7.0, 0);
            }
Если нет владельца у дома (if(!HouseInfo[h][hOwned])) то показываем информацию о доме без владельца, выгружаем информацию текста h_no_owner
Если же владелец есть, то отображается совершенно другая информация - h_any_owner
В public OnGameModeInit добавим запрос на загрузку:
PHP:
mysql_tquery(mysql_connect_ID,"SELECT * FROM `house`","LoadHouse","");
[HR][/HR]

Сохранение домов

PHP:
stock SaveHouse(houseid)
{
    new query_string[600] = "UPDATE `house` SET";

	format(query_string, sizeof(query_string), "%s `owner` = '%s',", query_string, HouseInfo[houseid][hOwner]);
	format(query_string, sizeof(query_string), "%s `owned` = '%d',", query_string, HouseInfo[houseid][hOwned]);
	format(query_string, sizeof(query_string), "%s `enter_pos_x` = '%f',", query_string, HouseInfo[houseid][henter_pos_x]);
	format(query_string, sizeof(query_string), "%s `enter_pos_y` = '%f',", query_string, HouseInfo[houseid][henter_pos_y]);
	format(query_string, sizeof(query_string), "%s `enter_pos_z` = '%f',", query_string, HouseInfo[houseid][henter_pos_z]);
	format(query_string, sizeof(query_string), "%s `exit_pos_x` = '%f',", query_string, HouseInfo[houseid][hexit_pos_x]);
	format(query_string, sizeof(query_string), "%s `exit_pos_y` = '%f',", query_string, HouseInfo[houseid][hexit_pos_y]);
	format(query_string, sizeof(query_string), "%s `exit_pos_z` = '%f',", query_string, HouseInfo[houseid][hexit_pos_z]);
	format(query_string, sizeof(query_string), "%s `price` = '%d',", query_string, HouseInfo[houseid][hPrice]);
	format(query_string, sizeof(query_string), "%s `level` = '%d',", query_string, HouseInfo[houseid][hLevel]);
	format(query_string, sizeof(query_string), "%s `interior` = '%d',", query_string, HouseInfo[houseid][hInt]);
	format(query_string, sizeof(query_string), "%s `car_pos_x` = '%f',", query_string, HouseInfo[houseid][hcar_pos_x]);
	format(query_string, sizeof(query_string), "%s `car_pos_y` = '%f',", query_string, HouseInfo[houseid][hcar_pos_y]);
	format(query_string, sizeof(query_string), "%s `car_pos_z` = '%f',", query_string, HouseInfo[houseid][hcar_pos_z]);
	format(query_string, sizeof(query_string), "%s `car_pos_angle` = '%f',", query_string, HouseInfo[houseid][hcar_pos_angle]);
	format(query_string, sizeof(query_string), "%s `vehicle` = '%d'", query_string, HouseInfo[houseid][hHouse_Car]);

    format(query_string, sizeof(query_string), "%s WHERE `id` = '%d'",query_string, HouseInfo[houseid][hID]);
    mysql_tquery(mysql_connect_ID, query_string, "", "");
    return true;
}
Тут даже и не знаю что сказать)
[HR][/HR]

Изменение 3D текста

Добавим stock который необходим для изменения "внешних" данных по дому(текст, пикап, иконка):
PHP:
stock House3DText()
{
	static const h_no_owner[] = "{FFDEAD}ID: {FFFFFF}[%d]\n{FFDEAD}Владелец: {FFFFFF}Нет\n{FFDEAD}Стоимость: {FFFFFF}%d\n{FFDEAD}Уровень: {FFFFFF}%d";
	static const h_any_owner[] = "{FFDEAD}ID: {FFFFFF}[%d]\n{FFDEAD}Владелец: {FFFFFF}%s\n{FFDEAD}Уровень: {FFFFFF}%d";

	new h_info[sizeof(h_any_owner) + ((3-2) + (24-2) + (20-2) + (5-2))];

    for(new h = 0; h <= TOTALHOUSE; h++)
    {
        if(!HouseInfo[h][hOwned])
        {
			format(h_info, sizeof(h_info), h_no_owner, HouseInfo[h][hID], HouseInfo[h][hPrice],HouseInfo[h][hLevel]);
			HouseInfo[h][hPickup] = CreatePickup(1273, 1, HouseInfo[h][henter_pos_x], HouseInfo[h][henter_pos_y], HouseInfo[h][henter_pos_z], -1);
			HouseInfo[h][hText]  = Create3DTextLabel(h_info, 0x008080FF, HouseInfo[h][henter_pos_x], HouseInfo[h][henter_pos_y], HouseInfo[h][henter_pos_z], 7, 0);
        	HouseInfo[h][hMapicon] = SetPlayerMapIcon(h, 12, HouseInfo[h][henter_pos_x], HouseInfo[h][henter_pos_y], HouseInfo[h][henter_pos_z], 31, -1, MAPICON_LOCAL);
		}
		else
    	{
			RemovePlayerMapIcon(HouseInfo[h][hMapicon], 12);
        	DestroyPickup(HouseInfo[h][hPickup]);
        	Delete3DTextLabel(HouseInfo[h][hText]);
			format(h_info, sizeof(h_info), h_any_owner, HouseInfo[h][hID], HouseInfo[h][hOwner],HouseInfo[h][hLevel]);
            HouseInfo[h][hPickup] = CreatePickup(1272, 1, HouseInfo[h][henter_pos_x], HouseInfo[h][henter_pos_y], HouseInfo[h][henter_pos_z], -1);
            HouseInfo[h][hText]  = Create3DTextLabel(h_info, 0xFFFFFF, HouseInfo[h][henter_pos_x], HouseInfo[h][henter_pos_y], HouseInfo[h][henter_pos_z], 7.0, 0);
		}
    }
}
Так как все функции стандартные, то и описывать их не вижу смысла, всю информацию можно подробно изучить на Wiki
| |
[HR][/HR]

Вход/выход

Давайте сделаем вход и выход в наш дом и из него. Я сделаю на ALT, кто-то может сделать как удобно для него, на другую клавишу или вообще командой:
Итак, для начала создадим макрос, для удобства работы:
PHP:
#define PRESSED(%0)\
	(((newkeys & (%0)) == (%0)) && ((oldkeys & (%0)) != (%0)))
Дальше идем в public OnPlayerKeyStateChange и добавим следующий код:
PHP:
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
    if(PRESSED(KEY_WALK))
    {
        for(new i; i < TOTALHOUSE; i++)
        {
            if (IsPlayerInRangeOfPoint(playerid, 2.0, HouseInfo[i][henter_pos_x], HouseInfo[i][henter_pos_y], HouseInfo[i][henter_pos_z]))
            {
                SetPlayerPos(playerid, HouseInfo[i][hexit_pos_x], HouseInfo[i][hexit_pos_y], HouseInfo[i][hexit_pos_z]);
                SetPlayerVirtualWorld(playerid, i + 50);
                SetPlayerInterior(playerid, HouseInfo[i][hInt]);
            }
            else if(IsPlayerInRangeOfPoint(playerid, 2.0, HouseInfo[i][hexit_pos_x],HouseInfo[i][hexit_pos_y], HouseInfo[i][hexit_pos_z]))
            {
                SetPlayerPos(playerid, HouseInfo[i][henter_pos_x], HouseInfo[i][henter_pos_y], HouseInfo[i][henter_pos_z]);
                SetPlayerVirtualWorld(playerid, 0);
                SetPlayerInterior(playerid, 0);
            }
        }
	}
	return 1;
}
PHP:
if (IsPlayerInRangeOfPoint(playerid, 2.0, HouseInfo[i][henter_pos_x], HouseInfo[i][henter_pos_y], HouseInfo[i][henter_pos_z]))
Если говорить русским языком, то "Если мы находимся у входа в дом, то попадаем в интерьер по координатам из нашей таблицы/массива"

Тоже самое у нас и с другой проверкой:
PHP:
else if(IsPlayerInRangeOfPoint(playerid, 2.0, HouseInfo[i][hexit_pos_x],HouseInfo[i][hexit_pos_y], HouseInfo[i][hexit_pos_z]))
Если мы находимся у выхода из дома, то попадаем на улицу.
[HR][/HR]

Покупка дома
Добавим команду покупки дома:
PHP:
CMD:buyhouse(playerid, params[])
{
	new house = -1,
		player_name[MAX_PLAYER_NAME];
		
    for(new h = 0; h < TOTALHOUSE; h++)
	{
		if(0 ==IsPlayerInRangeOfPoint(playerid,2.0, HouseInfo[h][henter_pos_x],HouseInfo[h][henter_pos_y], HouseInfo[h][henter_pos_z]) && HouseInfo[h][hOwned] == 0)
			continue;

		house = h;
	}

	if(house == -1)
	    return SendClientMessage(playerid, -1, "Ты не рядом с иконкой дома.");

	GetPlayerName(playerid, player_name, sizeof(player_name));
	strmid(HouseInfo[house][hOwner], player_name, 0, strlen(player_name), 255);
	SetPlayerInterior(playerid,HouseInfo[house][hInt]);
	SetPlayerPos(playerid,HouseInfo[house][hexit_pos_x],HouseInfo[house][hexit_pos_y],HouseInfo[house][hexit_pos_z]);
	SetPlayerVirtualWorld(playerid,house+50);
	HouseCar[house] = CreateVehicle(HouseInfo[house][hHouse_Car],HouseInfo[house][hcar_pos_x],HouseInfo[house][hcar_pos_y],HouseInfo[house][hcar_pos_z],HouseInfo[house][hcar_pos_angle],0,0, -1);
	HouseInfo[house][hOwned] = 1;
	SendClientMessage(playerid, -1, "Поздравляем с покупкой дома.");
	House3DText();
	SaveHouse(house);
	return true;
}
[От себя]: На данный момент, я не стал делать никаких проверок, на количество денег и прочее т.к. этого и не создавал, вы можете так же сделать свои проверки, на стоимость уровень и т.д. Дело вкуса конечно. Еще одна пометка, это обратить внимание на строку:
PHP:
strmid(HouseInfo[house][hOwner], player_name, 0, strlen(player_name), 255);
О функции .
player_name - замените на свой массив в котором хранится имя игрока, например pInfo[playerid][pName].

Так же если у вас уже есть система регистрации аккаунта, а я в самом первом абзаце говорил, что желательно, чтобы у вас уже была регистрация, для хранения данных об игроке.
Необходимо добавить массив pHouse - в котором будет проверка на ID дома, которым владеет игрок.
[HR][/HR]

Домашний транспорт
ВНИМАНИЕ! В данном пункте необходим массив с записью ID дома(pHouse).

Итак, вроде последний пункт моего урока, это домашний транспорт.
Я его решил сделать по такой схеме, что если игрок является владельцем дома и он онлайн, то домашний транспорт будет так же появляться. Как только игрок выходит из игры, его транспорт тоже пропадает. Сделал я это для того, чтобы не загружать карту, да и для удобства. Представляете если у вас например 500 домов, а где то в одном месте их немало и везде стоят машины, по мне так не удобно, но если вам нравится, когда карта забита машинами, то пожалуйста, как говорится дело вкуса. Не пугайтесь, когда создаете дом и устанавливаете машину у дома, а она не спавнится, это означает одно - нет владельца или же если он есть, то оффлайн.​

Ну что же. Добавим код в stock/public когда игрок залогинился:
PHP:
	if(pInfo[playerid][pHouse] > 0)
	{
	    new idx = pInfo[playerid][pHouse]-1;
		HouseCar[idx] = CreateVehicle(HouseInfo[idx][hHouse_Car],HouseInfo[idx][hcar_pos_x],HouseInfo[idx][hcar_pos_y],HouseInfo[idx][hcar_pos_z],HouseInfo[idx][hcar_pos_angle],HouseInfo[idx][hCar_Color_1],HouseInfo[idx][hCar_Color_2], -1);
        HouseInfo[idx][hMapicon] = SetPlayerMapIcon(playerid, 35, HouseInfo[idx][henter_pos_x], HouseInfo[idx][henter_pos_y], HouseInfo[idx][henter_pos_z], 35, -1, MAPICON_GLOBAL);
	}
Если наш игрок зашел на сервер, и у него есть дом, то появляется машина возле его дома, по координатам привязки.
Так же, я добавил чтобы иконка дома, когда он куплен, была видна из любого места на карте

Ну и соответственно удаление домашнего транспорта когда игрок выходит или нет владельца у дома:
PHP:
	if(!pInfo[playerid][pHouse])
	{
		DestroyVehicle(HouseCar[pInfo[playerid][pHouse]]);
	}
	if(pInfo[playerid][pHouse] > 0)
	{
	    new idx = pInfo[playerid][pHouse]-1;
		DestroyVehicle(HouseCar[idx]);
	}
Ну вот вроде и все. Должен ничего не забыть, а возможно и забыл, честно уже голова поехала) Так что если будут ошибки, напишите.

Кому нужны необходимы файлы:
Готовая таблица Исходник + таблица

Так же отдельное спасибо за реализацию: DeimoS | Saibot | Long
Всем спасибо кто дочитал до конца, пишите, что не так, не стесняйтесь.
Автор данного урока: Алексей.
Всем хорошего настроения и побольше знаний)

 
Последнее редактирование:
Сверху Снизу