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

Welcome to Форум About-samp.ru - крупнейшее самп сообщество.
Register now to gain access to all of our features. Once registered and logged in, you will be able to create topics, post replies to existing threads, give reputation to your fellow members, get your own private messenger, post status updates, manage your profile and so much more. If you already have an account, login here - otherwise create an account for free today!
Фотография

[Pawno, Урок 2]: Создание полноценного мода.


  • Авторизуйтесь для ответа в теме
В этой теме нет ответов

#1
iWuds

iWuds

    Администратор

  • Пользователи
  • PipPip
  • 28 сообщений

Шаг первый. 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, а также порталу павно-вики.






Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных