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

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

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

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

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

  • Администратор
  • Вставить ник
  • Цитировать
  • Раскрыть информацию
Приветствую! В этом уроке мы продолжим писать систему домов (часть 1) а точнее закончим ее. Нам осталось реализовать так сказать "игровую часть" системы (создание домов, покупка, вход, и так далее).

Шаг 5

Все команды в pawn создаются в колбэке OnPlayerCommandText (за исключением если у вас подключены сторонние разработки). На данный момент нам нужно написать команду для создания дома администратором:

if(strcmp("/acreatehouse", cmdtext, true, 13) == 0) // число 13 обозначает кол-во символов в команде включая "/".
	{
// Проверка на администратора, пример: if(PlayerInfo[playerid][pAdmin]==0)return SendClientMessage(playerid,-1,"У вас не хватает доступа к данной команде!");
		ShowPlayerDialog(playerid,D_H_CREATE_DESC,DIALOG_STYLE_INPUT,"Создание дома - описание","Введите описание для дома.","Далее","Закрыть"); // Создаем диалог
		return 1;
	}



Первый шаг создания дома это его Описание (как вы помните, в первом уроке мы создавали массив для этого: hDesc). Так же не забудьте поставить свою проверку на администратора в команде.

На этот диалог нам необходимо сделать действия (если игрок нажал на "Далее" произойдет ... иначе если он нажал на "закрыть"...). Для этого воспользуемся колбэком OnDialogResponse:

 case D_H_CREATE_DESC:
	    {
	        if(response) // Если игрок нажал "Далее"
	        {
	            if(!strlen(inputtext))return ShowPlayerDialog(playerid,D_H_CREATE_DESC,DIALOG_STYLE_INPUT,"Создание дома - описание","Введите описание для дома.","Далее","Закрыть"); // Если игрок ничего не ввел то показываем ему диалог снова
	            SetPVarString(playerid,"h_desc",inputtext); // Записываем в PVar описание чтобы в дальнейшем его использовать
	            ShowPlayerDialog(playerid,D_H_CREATE_PRICE,DIALOG_STYLE_INPUT,"Создание дома - цена","Введите цену для дома.","Далее","Назад"); // Показываем следующий диалог - цена дома.
	        }
		}



Хотел бы отметить, что я пользуюсь оператором switch, поэтому, заместо if(dialogid==D_H_CREATE_DESC) у меня case D_H_... . Итак, первый диалог готов, после того как игрок введет описание дома, выйдет диалог куда нужно будет ввести цену дома. Ниже создадим действия для 2-го диалога:

case D_H_CREATE_PRICE:
		{
		    if(response) // Если нажал "Да"
		    {
		        if(!strlen(inputtext))return ShowPlayerDialog(playerid,D_H_CREATE_PRICE,DIALOG_STYLE_INPUT,"Создание дома - цена","Введите цену для дома.","Далее","Назад"); 
		        SetPVarInt(playerid,"h_price",strval(inputtext)); // Сохраняем цену в PVar
				STR=""; // Очищаем массив (чтобы не было лишней информации
		        for(new i;i<sizeof(HInts);i++) // запускаем цикл для формирования следующего диалога в котором будет список с доступными интерьерами
		        {
		            strcat(STR,HInts[i][hiName]); // записываем в массив STR значение из HInts[i][hiName]
		            strcat(STR,"\n"); // Делаем переход на следующую строку т.к. стиль диалога = DIALOG_STYLE_LIST
		        }
		        ShowPlayerDialog(playerid,D_H_CREATE_INT,DIALOG_STYLE_LIST,"Создание дома - интерьер",STR,"Далее","Назад"); // Показываем диалог с готовым списком интерьеров
		    }
		    else DeletePVar(playerid,"h_desc"),ShowPlayerDialog(playerid,D_H_CREATE_DESC,
DIALOG_STYLE_INPUT,"Создание дома - описание","Введите описание для  дома.","Далее","Закрыть"); // Если же игрок нажал "Назад" показываем ему предыдущий диалог и удаляем то что было введено ранее (описание: DeletePVar).
		}



Создадим действия для диалога со списком интерьеров:

case D_H_CREATE_INT:
		{
		    if(response) // если нажал "Далее"
		    {
				SetPVarInt(playerid,"h_int",listitem); // Записываем в PVar номер списка (подсчет номера идет с 0 как в и массивах подсчет ячеек.
				ShowPlayerDialog(playerid,D_H_CREATE_CONF,DIALOG_STYLE_MSGBOX,"Создание дома - подтверждение","Вы действительно хотите создать дом в этом месте?","Создать","Отмена"); // Показываем диалог подтверждения
		    }
		    else DeletePVar(playerid,"h_price"),ShowPlayerDialog(playerid,D_H_CREATE_PRICE,
DIALOG_STYLE_INPUT,"Создание дома - цена","Введите цену для дома.","Далее","Назад"); // Иначе, если нажал "Назад" показываем предыдущий диалог и удаляем то что ввели ранее (цену: DeletePVar)
		}



И, нам осталось создать последний диалог, в котором и будет происходить создание дома:

case D_H_CREATE_CONF:
		{
		    if(response) // если игрок нажал "Создать"
	    	{
				m_h++,SaveHouseAmount(); // Увеличиваем общее кол-во домов
				new Float:x[3],str[32]; // Создаем необходимые массивы (для определения координат и получения данных из PVar'a - описание дома, то, что вводили ранее)
				GetPlayerPos(playerid,x[0],x[1],x[2]),GetPVarString(playerid,
"h_desc",str,32); // Определяем позиции игрока, заносим описание в str
				House[m_h][hX]=x[0],House[m_h][hY]=x[
1],House[m_h][hZ]=x[2],House[m_h][hPrice]
=GetPVarInt(playerid,"h_price"), // Присваиваем переменным дома необходимые значения
				House[m_h][hInterior]=GetPVarInt(playerid,"h_int"),House[
m_h][hVirtWorld]=m_h,strmid(House[m_h][hDesc],str,0,32,
32), 
				strmid(House[m_h][hOwner],"None",0,5,5);  // Записываем владельца дома как None
 				SaveHouse(m_h); // Сохраняем дом
				House[m_h][hPick]=CreatePickup(1273,23,x[0],x[1],
x[2],0); // Создаем пикап
				format(STR,128,"[Дом продается]\nОписание: %s\nЦена: $%d",House[m_h][hDesc],House[m_h][hPrice]
); // Форматируем строку для 3D информации
				House[m_h][hText]=Create3DTextLabel(STR,0xFFFFFFFF,x[0],x[
1],x[2]+0.5,10.0,0,0); // Создаем 3D текст с ин-цией
				GameTextForPlayer(playerid,"~g~House created",100,1); // Показываем текст игроку об успешном создании дома
                DeletePVar(playerid,"h_price"),DeletePVar(playerid,"h_desc"),
DeletePVar(playerid,"h_int"); // Удаляем уже не нужные нам PVar's
		    }
		    else DeletePVar(playerid,"h_price"),DeletePVar(playerid,"h_desc"),
DeletePVar(playerid,"h_int"); // Иначе если игрок нажал "Отмена" удаляем PVar's.
		}



Вот и все, создание дома у нас есть :3!

Шаг 6

Создадим все необходимые команды. Для начала создадим: покупку, продажу, закрыть / открыть замок (для администрации).

else if(strcmp("/ahlock", cmdtext, true, 7) == 0) // Команда для администрации (открыть / закрыть любой дом)
	{
		// Проверка на администратора
	    for(new h=1;h<=m_h;h++) // запускаем цикл
		{
		    if(!IsPlayerInRangeOfPoint(playerid,1.5,House[h][hX],House[
h][hY],House[h][hZ]))continue; // узнаем, стоит ли игрок рядом с одним из домов или нет (если нет, пропускаем оператором continue)
		    if(House[h][hLock]==1)House[h][hLock]=0,GameTextForPlayer(playerid,
"~g~House unlocked",100,1); // если замок дома закрыт - открываем
		    else House[h][hLock]=1,GameTextForPlayer(playerid,"~r~House locked",100,1); // если открыт - закрываем
			SaveHouse(h); // сохраняем дом
			return 1;
		}
	    return 1;
	}

else if(strcmp("/buyhouse", cmdtext, true, 9) == 0) // Покупка дома, тут все почти тоже самое
	{
		for(new h=1;h<=m_h;h++)
		{
		    if(!IsPlayerInRangeOfPoint(playerid,1.5,House[h][hX],House[
h][hY],House[h][hZ]))continue;
			if(GetPlayerMoney(playerid)<House[h][hPrice])return SendClientMessage(playerid,-1,"У вас не хватает средств!"); // Проверяем наличие средств
			if(strcmp(House[h][hOwner],"None",true)!=0)return SendClientMessage(playerid,-1,"Дом уже куплен!"); // узнаем есть ли владелец или нет при помощи сравнения строки
			strmid(House[h][hOwner],Name(playerid),0,24,24),UpdateHouse(h); // если нет, записываем нового владельца, обновляем 3д ин-цию и меняем пикап дома
                        SaveHouse(h);
			GivePlayerMoney(playerid,-House[h][hPrice]); // снимаем деньги
			SendClientMessage(playerid,-1,"Вы успешно купили дом!"); 
			return 1;
		}
		SendClientMessage(playerid,-1,"Рядом с вами нет дома!");
		return 1;
	}
	else if(strcmp("/sellhouse", cmdtext, true, 10) == 0) // продажа дома
	{
	    for(new h=1;h<=m_h;h++)
	    {
	        if(!IsPlayerInRangeOfPoint(playerid,1.5,House[h][hX],House[
h][hY],House[h][hZ]))continue;
	        if(!strcmp(House[h][hOwner],Name(playerid),true)) // если игрок владелец этого дома, тогда...
	        {
	            strmid(House[h][hOwner],"None",0,5,5),UpdateHouse(h);
                    SaveHouse(h);
	            GivePlayerMoney(playerid,House[h][hPrice]/2); // отдаем игроку пол цены за дом
	            SendClientMessage(playerid,-1,"Вы продали свой дом!");
				return 1;
	        }
	    }
	    //SendClientMessage(playerid,-1,"Рядом с вами нет дома!");
	    return 1;
	}



Теперь нужно сделать вход и выход из дома + возможность открывать / закрывать замки для владельцев домов:

else if(strcmp("/enter", cmdtext, true, 6) == 0) // Вход
	{
	    for(new h=1;h<=m_h;h++)
	    {
	        if(!IsPlayerInRangeOfPoint(playerid,1.5,House[h][hX],House[
h][hY],House[h][hZ]))continue;
	        if(strcmp(House[h][hOwner],Name(playerid),true)!=0 && House[h][hLock]==1)return SendClientMessage(playerid,-1,"Дом закрыт!"); // Если вы не владелец и дом закрыт- не пустит
	        SetPlayerPos(playerid,HInts[House[h][hInterior]][hiX]
,HInts[House[h][hInterior]][hiY],HInts[House[
h][hInterior]][hiZ]); // Тут, мы при помощи номера ячейки узнаем координаты внутри дома
	        SetPlayerInterior(playerid,HInts[House[h][hInterior]][
hiInt]); // + узнаем его ид (HInts[номер_ячейки][hiInt]
	        SetPlayerVirtualWorld(playerid,House[h][hVirtWorld]); // Присваиваем игроку вирт. мир
		}
	    return 1;
	}
	else if(strcmp("/exit", cmdtext, true, 5) == 0) // выход из дома
	{
	    for(new h=1;h<=m_h;h++)
	    {
	        if(IsPlayerInRangeOfPoint(playerid,1.5,HInts[House[h][hInterior]
][hiX],HInts[House[h][hInterior]][hiY]
,HInts[House[h][hInterior]][hiZ]) && GetPlayerVirtualWorld(playerid)==House[h][hVirtWorld])
	        {
	            SetPlayerPos(playerid,House[h][hX],House[h][hY],House[
h][hZ]);
	            SetPlayerVirtualWorld(playerid,0),SetPlayerInterior(playerid,0);
			}
		}
	    return 1;
	}
	else if(strcmp("/hlock", cmdtext, true, 6) == 0) // Закрываем замок дома
	{
	    for(new h=1;h<=m_h;h++)
	    {
	        if(!IsPlayerInRangeOfPoint(playerid,1.5,House[h][hX],House[
h][hY],House[h][hZ]))continue;
	        if(strcmp(House[h][hOwner],Name(playerid),true)!=0)return SendClientMessage(playerid,-1,"У вас нет ключей от этого дома!"); // Сравниваем владельца дома с ником игрока, если не совпадает - выводим сообщение
	        if(House[h][hLock]==0)House[h][hLock]=1,SaveHouse(h),
GameTextForPlayer(playerid,"~r~House locked",100,1); // если дом открыт - закрываем (0 открыт / 1 закрыт)
	        else if(House[h][hLock]==1)return SendClientMessage(playerid,-1,"Дом уже закрыт!"); // иначе выводим сообщение
			return 1;
		}
	    return 1;
	}
	else if(strcmp("/hopen", cmdtext, true, 6) == 0) // Открываем дом, все тоже самое, только меняем условия
	{
	    for(new h=1;h<=m_h;h++)
	    {
	        if(!IsPlayerInRangeOfPoint(playerid,1.5,House[h][hX],House[
h][hY],House[h][hZ]))continue;
	        if(strcmp(House[h][hOwner],Name(playerid),true)!=0)return SendClientMessage(playerid,-1,"У вас нет ключей от этого дома!");
	        if(House[h][hLock]==1)House[h][hLock]=0,SaveHouse(h),
GameTextForPlayer(playerid,"~g~House unlocked",100,1);
	        else if(House[h][hLock]==0)return SendClientMessage(playerid,-1,"Дом уже открыт!");
			return 1;
		}
	    return 1;
	}



Конец

Вот и все, наша система готова. Система тестировалась мною, никаких багов не обнаружил. Если вдруг вы что-нибудь найдете, просьба отписаться в данной теме; так же с вопросами, возникли какие-либо вопросы - пишите :).

Чуть не забыл, в папку scriptfiles поставьте:
houses.zip [336байт]

В public OnGameModeInit нашу функцию загрузки:
LoadHouses();



p.s. Возможна доработка / настройка системы под вас, не бесплатно, по этому поводу обращаться в ЛС!

Автор: Mike™

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

Сказали спасибо 18:

#2
Пользователь офлайн   Electorat 

  • Пользователь
  • Вставить ник
  • Цитировать
  • Раскрыть информацию
Майк ты чудо. побольше бы таких людей как ты:)
0

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

  • Пользователь
  • Вставить ник
  • Цитировать
  • Раскрыть информацию
Компилируется 0 ошибок. при запуске выходит вот это:
кто знает как исправить?

Изображение
0

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

  • Эксперт
  • Вставить ник
  • Цитировать
  • Раскрыть информацию
Microsoft Visual C++ 2010 установи скачать.
2

Сказали спасибо 2:

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

  • Прохожий
  • Вставить ник
  • Цитировать
  • Раскрыть информацию
В команду /buyhouse после строки
SendClientMessage(playerid,-1,"Вы успешно купили дом!"); 

вставь строку
SaveHouse(h);


иначе при рестарте сервера дома будут возращены на продажу.
0

Сказали спасибо 1:
opzz 

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

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

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

В команду /buyhouse после строки
SendClientMessage(playerid,-1,"Вы успешно купили дом!"); 

вставь строку
SaveHouse(h);


иначе при рестарте сервера дома будут возращены на продажу.


Спасибо, не заметил, уже поправил.
1

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

  • Брат за брата
  • Вставить ник
  • Цитировать
  • Раскрыть информацию
Молодец Mike! Простая система, но для ДМ сервером пойдёт! :steep:
-1

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

  • Прохожий
  • Вставить ник
  • Цитировать
  • Раскрыть информацию
Думаю в команде /hlock and /hopen тоже бы не помешало поставить строчку
SaveHouse(h);


Чтобы при рестарте дом небыл открыт или закрыт, если перед рестартом ты закрыл или открыл свой дом.
0

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

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

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

Думаю в команде /hlock and /hopen тоже бы не помешало поставить строчку
SaveHouse(h);


Чтобы при рестарте дом небыл открыт или закрыт, если перед рестартом ты закрыл или открыл свой дом.


Там уже есть.
0

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

  • Прохожий
  • Вставить ник
  • Цитировать
  • Раскрыть информацию
Майк помоги плиз у меня когда компилируешь всё норм а только начинаешь включать мод он мне в консоли пишет Script[gamemodes/new1.amx]:Run time error 19:"File or functional is not found" что мне делать?(
0

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


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

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