Форум Pawn.Wiki - Воплоти мечту в реальность!: Создание полноценного мода. [Урок 2] - Форум Pawn.Wiki - Воплоти мечту в реальность!

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

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

[ Урок ]
Создание полноценного мода. [Урок 2]
Оценка: ***** 6 Голосов

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

  • Эксперт
  • Вставить ник
  • Раскрыть информацию

Здравствуйте, уважаемые пользователи pawn-wiki!

Если вы читаете это, значит я уже играю в CS 1.6 и написал второй урок.
С Вами Stich, и я буду вместе с Вами писать мод, на основе которого Вы сможете сделать свой сервер.
Мод будет жанра Role Play, написан с нуля, с системой сохранения аккаунтов посредством базы данных.



В этом уроке мы сделаем:
  • Систему регистрации и авторизации в диалоговых окнах.
  • Респавн для новичков.
  • Текстдрав сайта в правом верхнем углу экрана.





Итак, приступим:

Шаг первый. Where is my mode?
Входим в pawno.exe и открываем наш мод, который получился в ходе выполнения первого урока.
Не забываем включить какой-нибудь рокешник погромче. Ну это уже на любителя.
Вот и закончился первый шаг.



Шаг второй. Как мне войти?
Столько вопросов в названиях шагов, мне аж страшно стало.
Так как же всё-таки войти? Легко:
В "OnPlayerConnect(playerid)" вставляем это:
for(new i; i < 20; i++)	SendClientMessage(playerid, -1, ""); // Создает 20 пустых строк, это в принципе не обязательно, но с этим красивее.

ShowPlayerDialog(playerid,9815,DIALOG_STYLE_MSGBOX,"{FFFF00}MyRP, mode by Stich{FFFFFF}","   {ffe4b2}Добро пожаловать, на сервер.\n   {ffe4b2}Подождите полной загрузки сервера\n      и нажмите далее","Далее","Выход");


Диалог позволяет человеку выбрать, играть на сервере или нет. Во-первых, он заставляет человека подождать какое-то время, а во-вторых, он помогает MySQL определить, есть ли такой игрок в базе.
Далее, в "OnDialogResponse":
if(dialogid == 9815)
	{
		if(response)
		{
			new pname[256]; // Объявляем переменную имени игрока.
   			GetPlayerName(playerid, pname, sizeof(pname)); // Узнаем имя игрока и записываем в переменную.
  			format(query, sizeof(query), "SELECT * FROM "TABLE_ACCOUNT" WHERE name = '%s'",  pname); // Выбрать * из таблицы с аккаунтами тот аккаунт, имя которого - наша переменная.
			mysql_query(query); // Отправляем запрос.
			mysql_store_result(); // Очищаем память.
   			if(mysql_fetch_row_format(query)) // Если аккаунт найден:
   			{
   				ShowPlayerDialog(playerid, 0, DIALOG_STYLE_INPUT,
   				"{FFFF00}MyRP, mode by Stich{FFFFFF}",
   				"{FFFFFF}Здравствуйте, пожалуйста введите Ваш пароль\n{FFFFFF}Ваш аккаунт {00ff23}зарегистрирован{FFFFFF} в базе данных.",
				"Войти", "Выход");
			}
			else
			{
		 		ShowPlayerDialog(playerid, 1, DIALOG_STYLE_INPUT,
				"{FFFF00}MyRP, mode by Stich{FFFFFF}",
				"{FFFFFF}Здравствуйте, пожалуйста введите Ваш пароль для регистрации\n{FFFFFF}Ваш аккаунт {ff001c}не зарегистрирован{FFFFFF} в базе данных.",
				"Далее", "Выход");
			}
		}
	}


Теперь добавляем те самые диалоги - 0 и 1, соответствующие нашим диалогам с регистрацией и авторизацией:
if(dialogid == 0) // Если зарегистрирован:
    {
        if(response)
        {
			if(strlen(inputtext) != 0) // Если в поле пароля что то ввели, то делаем следущее:
  			{
     			new pname2[MAX_PLAYER_NAME]; // Объявляем ник.
			    GetPlayerName(playerid, pname2, MAX_PLAYER_NAME); // Узнаем ник.
			    if(!strcmp(inputtext, GetAccount(pname2, "password"), true)) OnPlayerLogin(playerid); // Дословно: Если введенный текст соответствует паролю аккаунта, то логиним игрока.
		        else // Если введенный текст НЕ соответствует паролю, то опять повторяем диалог:
		        {
		          	ShowPlayerDialog(playerid, 0, DIALOG_STYLE_INPUT,
					"{FFFF00}MyRP, mode by Stich{FFFFFF}",
					"{FFFFFF}Здравствуйте, пожалуйста введите Ваш пароль\nВаш аккаунт {00ff23}зарегистрирован{FFFFFF} в базе данных.",
					"Войти", "Выход");
	          	}
          	}
		  	else  // Если ничего не ввели, то опять повторяем диалог:
		  	{
    			ShowPlayerDialog(playerid, 0, DIALOG_STYLE_INPUT,
   			 	"{FFFF00}MyRP, mode by Stich{FFFFFF}",
    			"{FFFFFF}Здравствуйте, пожалуйста введите Ваш пароль\n{FFFFFF}Ваш аккаунт {00ff23}зарегистрирован{FFFFFF} в базе данных.",
    			"Войти", "Выход");
 			}
        }
        else // Если игрок нажал выход, то:
        {
            Kick(playerid); // Вышвыриваем его, зачем такие нужны?
        }
    }



if(dialogid == 1) // Если НЕ зарегистрирован:
    {
        if(response)
        {
		    if(strlen(inputtext) != 0) // Если в поле пароля что то ввели, то делаем следущее:
		    {
		      	OnPlayerRegister(playerid,inputtext); // Регистрируем
		    }
		    else // Если нет, то:
		    {
		       	ShowPlayerDialog(playerid, 1, DIALOG_STYLE_INPUT,
		        "{FFFF00}MyRP, mode by Stich{FFFFFF}",
		        "{FFFFFF}Здравствуйте, пожалуйста введите Ваш пароль для регистрации\n{FFFFFF}Ваш аккаунт {ff001c}не зарегистрирован{FFFFFF} в базе данных.",
		        "Далее", "Выход");
		    }
        }
        else
        {
            Kick(playerid);  // Опять вышвыриваем его, че он опять пришел?
        }
    }



Добавляем три stock'a, желательно после "OnGameModeInit", но перед "OnPlayerConnect":
stock OnPlayerLogin(playerid) // Логинизация игрока
{
    new pname[256];
    GetPlayerName(playerid, pname, sizeof(pname));
   	format(query,sizeof(query), "SELECT * FROM "TABLE_ACCOUNT" WHERE name = '%s' LIMIT 1",pname); // Вытаскиваем из базы данных игрока с ником равным "pname"
	mysql_query(query);
	mysql_store_result();
	if(mysql_fetch_row(query) == 1)
  	{
	    sscanf(query, "p<|>s[32]s[32]iiiiiiiiiiiiiiii", // Здесь все просто: s - string, то есть то, что, проще говоря, с буквами. i - цифры, такие как уровень, ID игрока, скин и так далее. f - Float:, то бишь, позиция, любая.
		pname,
		Player[playerid][pPassword],
		Player[playerid][pID],
		Player[playerid][pLevel],
		Player[playerid][pMute],
		Player[playerid][pAdmin],
		Player[playerid][pMoney],
		Player[playerid][pExp],
		Player[playerid][pVip],
		Player[playerid][pSkin],
		Player[playerid][pLeader],
		Player[playerid][pMember],
		Player[playerid][pBan],
		Player[playerid][pKills],
		Player[playerid][pDeaths],
		Player[playerid][pHealths],
		Player[playerid][pClass],
		Player[playerid][pLang]
		);
     	mysql_free_result();
	}
	
	if(Player[playerid][pBan] == 1) // Если игрок забанен на сервере, то:
	{
	    SendClientMessage(playerid,COLOR_RED,"x {FFFFFF}Ваш аккаунт заблокирован на сервере."); // Пишем ему об этом.
	    Kick(playerid); // И кикаем.
	}

	if(Player[playerid][pVip] >= 1)
	{
	    new strin[200];
		format(strin, sizeof(strin), "{FF0000}• {FFFFFF}Ваш аккаунт авторизован с VIP статусом {77e654}[%d lvl].", Player[playerid][pVip]);
		SendClientMessage(playerid,COLOR_LIGHTRED,strin);
	}

	if(Player[playerid][pAdmin] >= 1)
	{
	    new strin[200];
	    format(strin, sizeof(strin), "{FF0000}• {FFFFFF}Ваш аккаунт авторизован со статусом администратора  {77e654}[%d lvl].", Player[playerid][pAdmin]);
		SendClientMessage(playerid,COLOR_LIGHTRED,strin);
	}
	
	new strin[200];
	format(strin, sizeof(strin), "{FF0000}• {FFFFFF}Добро пожаловать, {77e654}%s.", GetPlayerName(playerid));
	SendClientMessage(playerid,COLOR_LIGHTRED,strin);

	SetSpawnInfo(playerid, 255, 0, 0, 0, 0, 1.0, -1, -1, -1, -1, -1, -1);
	ServerGivePlayerMoney(playerid, Player[playerid][pMoney]);
	SpawnPlayer(playerid);
}




 
stock OnPlayerRegister(playerid, pass[]) // Регистрация:
{
    new pname[256]; 
    GetPlayerName(playerid, pname, sizeof(pname));
   	format(query, sizeof(query), "INSERT INTO "TABLE_ACCOUNT" (name, password) VALUES ('%s', '%s')" // Вносим в таблицу с акаунтами имя и пароль игрока.
	,pname, pass);
	mysql_query(query); 
}



stock OnPlayerSave(playerid)
{
	if(IsPlayerConnected(playerid))
	{
		new src[1024], pname[256];
		GetPlayerName(playerid, pname, sizeof(pname));
		format(query,sizeof(query),"UPDATE "TABLE_ACCOUNT" SET "); // Обновляем таблицу с аккаунтами:


		format(src,sizeof(src),"password=%i,",Player[playerid][pPassword]);
		strcat(query,src,sizeof(query));
		format(src,sizeof(src),"userid=%i,",Player[playerid][pID]);
		strcat(query,src,sizeof(query));
		format(src,sizeof(src),"level=%i,",Player[playerid][pLevel]);
		strcat(query,src,sizeof(query));
		format(src,sizeof(src),"mute=%i,",Player[playerid][pMute]);
		strcat(query,src,sizeof(query));
		format(src,sizeof(src),"admin=%i,",Player[playerid][pAdmin]);
		strcat(query,src,sizeof(query));
		format(src,sizeof(src),"money=%i,",GetPlayerMoney(playerid));
		strcat(query,src,sizeof(query));
		format(src,sizeof(src),"exp=%i,",Player[playerid][pExp]);
		strcat(query,src,sizeof(query));
		format(src,sizeof(src),"vip=%i,",Player[playerid][pVip]);
		strcat(query,src,sizeof(query));
		format(src,sizeof(src),"skin=%i,",Player[playerid][pSkin]);
		strcat(query,src,sizeof(query));
		format(src,sizeof(src),"leader=%i,",Player[playerid][pLeader]);
		strcat(query,src,sizeof(query));
		format(src,sizeof(src),"member=%i,",Player[playerid][pMember]);
		strcat(query,src,sizeof(query));
		format(src,sizeof(src),"Ban=%i",Player[playerid][pBan]);
		strcat(query,src,sizeof(query));
		format(src,sizeof(src),"kills=%i,",Player[playerid][pKills]);
		strcat(query,src,sizeof(query));
		format(src,sizeof(src),"deaths=%i,",Player[playerid][pDeaths]);
		strcat(query,src,sizeof(query));
		format(src,sizeof(src),"healths=%i,",Player[playerid][pHealths]);
		strcat(query,src,sizeof(query));
		format(src,sizeof(src),"class=%i,",Player[playerid][pClass]);
		strcat(query,src,sizeof(query));
		format(src,sizeof(src),"lang=%i,",Player[playerid][pLang]);
		strcat(query,src,sizeof(query));


		format(src,sizeof(src)," WHERE name='%s'",pname); // У игрока имя которого - pname
		strcat(query,src,sizeof(query));
		mysql_query(query);
	}
	else SendClientMessage(playerid,COLOR_WHITE,"");
}



И необходимый:
stock GetAccount(username[], obtaining[])
{
	new QueryAcc[255];
	format(QueryAcc, sizeof(QueryAcc), "SELECT %s FROM "TABLE_ACCOUNT" WHERE name = '%s' LIMIT 1", obtaining, username);
    mysql_query(QueryAcc);
    mysql_store_result();
    if(mysql_fetch_row(QueryAcc) == 1)
    {
    	mysql_free_result();
    	return QueryAcc;
    }
    return QueryAcc;
}





Шаг третий. Где я?
Так как у нас будет сервер RP жанра, то однозначно у нас будут фракции, мафии и банды. Значит, для каждой должен быть предусмотрен свой спавн.

В "OnPlayerSpawn":
if(Player[playerid][pLeader] == 0 && Player[playerid][pMember] == 0) // Если игрок нигде не состоит, то:
{
        SetPlayerPos(playerid, 2012.0760,-1283.5067,28.4881); // Отправляем его на эти координаты.
	SetPlayerInterior(playerid,0); // Ставим нулевой интерьер, так как он на улице.
	SetPlayerColor(playerid,0x007FFAAA); // Ставим синий цвет, измените на свой или уберите вообще.
	SetCameraBehindPlayer(playerid); // И двигаем камеру к игроку во избежании возможных багов с камерой.
}


Вот и все, ничего сложного. ;)



Шаг четвертый. А где сайт?
Как мне надоели эти вопросы...
Уроков по текстдравам на форуме очень и очень много. Но так как мы пишем мод и они нам нужны, я не буду перенаправлять вас в другие темы.
Итак, ко всем "new":
new Text:SiteName[MAX_PLAYERS]; // Объявляем переменную текстдрава сайта.


Далее, в "OnPlayerConnect":
        SiteName[playerid] = TextDrawCreate(500.000000, 2.000000, "~w~www.~g~PAWN-WIKI~w~.ru"); // Зеленым цветом написан адрес нашего любимого форума. ~g~ - зеленый, ~w~ - белый.
	TextDrawBackgroundColor(SiteName[playerid], 255); // Цвет фона, 255 - прозрачный
	TextDrawFont(SiteName[playerid], 2); // Тип шрифта.
	TextDrawLetterSize(SiteName[playerid], 0.329999, 1.600000); // Хз, если честно.
	TextDrawColor(SiteName[playerid], -1); // Цвет. 
	TextDrawSetOutline(SiteName[playerid], 0); // Обводка.
	TextDrawSetProportional(SiteName[playerid], 1); // Пропорция.
	TextDrawSetShadow(SiteName[playerid], 1); // Тень.





Пока что, все.
Будут вопросы - обращайтесь сюда.

Удачи!



Изображение

Изображение





Автор: Stich. При копировании указывать автора - обязательно.

Сообщение отредактировал Stich: 14 января 2013 - 09:40

37

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

  • Новичок
  • Вставить ник
  • Раскрыть информацию
жирный плюссс)
0

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

  • Эксперт
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияvasyok (18 декабря 2012 - 10:21) писал:

жирный плюссс)

Какие вы быстрые, однако. Спасибо.
0

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

  • Местный
  • Вставить ник
  • Раскрыть информацию
Впечатлило. :)
0

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

  • Местный
  • Вставить ник
  • Раскрыть информацию
Молодец , продолжай в том же духе . :wink:
0

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

  • Прохожий
  • Вставить ник
  • Раскрыть информацию
+
Надеюсь, не забросишь уроки, как делают многие
0

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

  • Эксперт
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияFormelOne (18 декабря 2012 - 11:34) писал:

+
Надеюсь, не забросишь уроки, как делают многие

Не заброшу, на то я и модератор.
0

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

  • Новичок
  • Вставить ник
  • Раскрыть информацию
:mellow:
Хотя РП не люблю
Лови плюс, заберу у тебя текстдрав :laugh:
0

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

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

Просмотр сообщенияStich (18 декабря 2012 - 11:51) писал:

Не заброшу, на то я и модератор.

были бы и не модераторы кто берётся делать уроки по написанию мода с нуля такими ответственными :smile:
0

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

  • Пользователь
  • Вставить ник
  • Раскрыть информацию
C:\Games\Industrial-rp\gamemodes\Industrial.pwn(152) : warning 202: number of arguments does not match definition
C:\Games\Industrial-rp\gamemodes\Industrial.pwn(152) : warning 202: number of arguments does not match definition
C:\Games\Industrial-rp\gamemodes\Industrial.pwn(156) : error 017: undefined symbol "ServerGivePlayerMoney"
C:\Games\Industrial-rp\gamemodes\Industrial.pwn(490) : error 017: undefined symbol "GetAccount"



152:
format(strin, sizeof(strin), "{FF0000}• {FFFFFF}Добро пожаловать, {77e654}%s.", GetPlayerName(playerid));


156:
ServerGivePlayerMoney(playerid, Player[playerid][pMoney]);


490:
 if(!strcmp(inputtext, GetAccount(pname2, "password"), true)) OnPlayerLogin(playerid);

Сообщение отредактировал cccmertnik: 18 декабря 2012 - 18:43

0

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


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

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


Яндекс.Метрика