Простая система Голода/Жажды (SQLite)

Описание: Уроки по скриптингу
Модератор: SJplayer

Prezident M
Автор темы, Ефрейтор
Ефрейтор
Аватара
Prezident M
Автор темы, Ефрейтор
Ефрейтор
Сообщения: 28
Зарегистрирован: 9 июля 2013
С нами: 10 лет 8 месяцев

#1 Prezident » 17 января 2014, 21:42

Автор: Voxel
В этом уроке мы будем использовать SQLite для сохранения статистики игроков.

Прежде всего мы добавляем нужные enum для нашей статистики:

Код: Выделить всё

enum USER_DATA
{
    
USER_ID//здесь мы сохраняем ID учетной записи в базе
    
USER_NAME[MAX_PLAYER_NAME], //то же самое относится и к имени
    
USER_PASSWORD[129], //сохранить пароль
    
USER_HUNGER//голод игроков
    
USER_THIRST//и жажда

    
boolUSER_LOGGED_IN
};

new 
User[MAX_PLAYERS][USER_DATA];
new 
DBDatabase


Далее мы создаём остальную часть базы данных:

Код: Выделить всё

public OnFilterScriptInit()
{
    
Database db_open("server.db");
    
db_query(Database"CREATE TABLE IF NOT EXISTS users (userid INTEGER PRIMARY KEY AUTOINCREMENT, username VARCHAR(24) COLLATE NOCASE, password VARCHAR(129), hunger INTEGER DEFAULT 0 NOT NULL, thirst INTEGER DEFAULT 0 NOT NULL)");
    
AddPlayerClass(12528.9143,-1667.7504,15.1689,91.2860,0,0,0,0,0,0);
    return 
1;
}

public 
OnPlayerConnect(playerid)
{
    for(new 
i_USER_DATA; ++iUser[playerid][USER_DATAi] = 0;

    
GetPlayerName(playeridUser[playerid][USER_NAME], MAX_PLAYER_NAME);

    new 
Query[71], DBResultResult;
    
format(Querysizeof(Query), "SELECT password FROM users WHERE username = '%s' LIMIT 0, 1"DB_Escape(User[playerid][USER_NAME]));
    
Result db_query(DatabaseQuery);
    if(
db_num_rows(Result))
    {
        
db_get_field_assoc(Result"password"User[playerid][USER_PASSWORD], 129);
        
ShowPlayerDialog(playerid0DIALOG_STYLE_PASSWORD"Login pannel""Login pannel""Please login to play""Login""Exit");
    }
    else 
ShowPlayerDialog(playerid1DIALOG_STYLE_PASSWORD"Register pannel""Please register to play""Register""Exit");
    
db_free_result(Result);
    return 
1;
}

public 
OnPlayerDisconnect(playeridreason)
{
    if(
User[playerid][USER_LOGGED_IN] == true)
    {
        new 
Query[128];
        
format(Querysizeof(Query), "UPDATE users SET hunger= %s, thirst = %s WHERE username = '%s'"User[playerid][USER_HUNGER], User[playerid][USER_THIRST], DB_Escape(User[playerid][USER_NAME]));
        
db_query(DatabaseQuery);
    }
    for(new 
i_USER_DATA; ++iUser[playerid][USER_DATAi] = 0;
    return 
1;
}

public 
OnPlayerSpawn(playerid)
{
    return 
1;
}

public 
OnPlayerDeath(playeridkilleridreason)
{
    return 
1;
}

public 
OnDialogResponse(playeriddialogidresponselistiteminputtext[])
{
    if(
dialogid == 0)
    {
        if(
response)
        {
            if(!
inputtext[0]) return ShowPlayerDialog(playerid0DIALOG_STYLE_PASSWORD"Login pannel""Please login to play""Login""Exit");
            new 
buf[129];
            
WP_Hash(buf129inputtext);
            if(!
strcmp(bufUser[playerid][USER_PASSWORD], false))
            {
                new 
Query[75], DBResultResult;
                
format(Querysizeof(Query), "SELECT * FROM users WHERE username = '%s' LIMIT 0, 1"DB_Escape(User[playerid][USER_NAME]));
                
Result db_query(DatabaseQuery);
                if(
db_num_rows(Result))
                {
                    
db_get_field_assoc(Result"userid"Query7);
                    
User[playerid][USER_ID] = strval(Query);

                    
db_get_field_assoc(Result"hunger"Query3);
                    
User[playerid][USER_HUNGER] = strval(Query);

                    
db_get_field_assoc(Result"thirst"Query3);
                    
User[playerid][USER_THIRST] = strval(Query);

                    
User[playerid][USER_LOGGED_IN] = true;

                    
SendClientMessage(playerid, -1"You have successfully logged in to your account!");
                }
                
db_free_result(Result);
            }
            else
            {
                
SendClientMessage(playerid, -1"Incorrect password!");
                
ShowPlayerDialog(playerid0DIALOG_STYLE_PASSWORD"Login pannel""Please login to play""Login""Exit");

            }
        }
        else 
Kick(playerid);
        return 
1;
    }
    if(
dialogid == 1)
    {
        if(
response)
        {
            if(!
IsValidPassword(inputtext))
            {
                
SendClientMessage(playerid, -1"The password is invalid, Valid characters are: A-Z, a-z, 0-9");
                
ShowPlayerDialog(playerid1DIALOG_STYLE_PASSWORD"Register pannel""Please register to play""Register""Exit");
                return 
1;
            }
            if(
strlen(inputtext) < || strlen(inputtext) > 24)
            {
                
SendClientMessage(playerid, -1"The password is invalid, Its lenght should be 3-24 characters");
                
ShowPlayerDialog(playerid1DIALOG_STYLE_PASSWORD""COL_BLUE"SERVER NAME"COL_WHITE" Register pannel""Please register to play""Register""Exit");
                return 
1;
            }
            new 
Query[208];
            
WP_Hash(User[playerid][USER_PASSWORD], 129inputtext);
            
format(Querysizeof(Query), "INSERT INTO users (username, password) VALUES ('%s', '%s')"DB_Escape(User[playerid][USER_NAME]), DB_Escape(User[playerid][USER_PASSWORD]));
            
db_query(DatabaseQuery);

            
User[playerid][USER_LOGGED_IN] = true;
            
SendClientMessage(playerid, -1"You have just registered to our server! You have been automatically logged in!");
        }
        else 
Kick(playerid);
        return 
1;
    }
    return 
1;
}

stock DB_Escape(text[])
{
    new 
ret80 ], chij;
    while((
ch text[i++]) && sizeof(ret))
    {
        if(
ch == '\'')
        {
            if(
sizeof(ret) - 2)
            {
                
ret[j++] = '\'';
                
ret[j++] = '\'';
            }
        }
        else if(
sizeof(ret))
        {
            
ret[j++] = ch;
        }
        else
        {
            
j++;
        }
    }
    
ret[sizeof(ret) - 1] = '\0';
    return 
ret;
}

stock IsValidPassword(const password[])
{
    for(new 
0password[i] != EOS; ++i)
    {
        switch(
password[i])
        {
            case 
'0'..'9''A'..'Z''a'..'z': continue;
            default: return 
0;
        }
    }
    return 
1;


Теперь у нас есть база данных, чтобы сохранить наш голод и жажду , и мы будем устанавливать статистику игрока, когда он впервые регистрирует на сервере:

Код: Выделить всё

User[playerid][USER_LOGGED_IN] = true;
SendClientMessage(playerid, -1"Вы только что зарегистрировались на нашем сервере и автоматически авторизованы!");
User[playerid][USER_HUNGER] == 100); //мы устанавливаем голод 100
User[playerid][USER_THIRST] == 100); //и жажду 


Теперь, когда мы установили значения, мы можем начать делать функции, чтобы уменьшить эту статистику. Пример:

Код: Выделить всё

//Вы должны это определить в верху скрипта (дефайн)
#define PRESSED(%0) \
    
(((newkeys & (%0)) == (%0)) && ((oldkeys & (%0)) != (%0)))

//каждый раз вы прыгаете вы потеряете немного энергии, что означает у получите больше голода и жажды
public OnPlayerKeyStateChange(playeridnewkeysoldkeys)
{
     if(
PRESSED(KEY_JUMP))
     {
          
User[playerid][USER_HUNGER] -= 5); //берем 5 из голода игрока
          
User[playerid][USER_THIRST] -= 7); //и 7 жажды
     
}
     return 
1;


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

Код: Выделить всё

public OnPlayerKeyStateChange(playeridnewkeysoldkeys)
{
     if(
PRESSED(KEY_JUMP))
     {
          if(
User[playerid][USER_HUNGER] <= 10 || User[playerid][USER_THIRST] <= 10)
          {
               
SendClientMessage(playerid, -1"Вам ​​не хватает энергии, чтобы прыгать, поешьте и попейте"); 
               new 
Float:XFloat:YFloat:Z;
               
GetPlayerPos(playeridxyz);
               
SetPlayerPos(playeridxyz);
               
//быстрый способ отключить прыжки (не проверено)
          
}
          else
          {
               
//если игрок имеет больший голод и жажду (10)
               
User[playerid][USER_HUNGER] -= 5); //берем 5 голода
               
User[playerid][USER_THIRST] -= 7); //7 жажды
          
}
     }
     return 
1;


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

Код: Выделить всё

//example
if(listitem == 0//asuming you have a dialog and this is list item 0 which would be a burger or something
{
     
User[playerid][USER_HUNGER] += 20); 
     
SendClientMessage(playerid, -1"Вы съели гамбургер, +20 голод");
}
if(
listitem == 1//and this would be a soda or such
{
     
User[playerid][USER_THIRST] += 20); 
     
SendClientMessage(playerid, -1"Вы пили содовую, +20 жажду" );


Теперь мы будем делать команду /energy, чтобы проверить голод и жажду:

Код: Выделить всё

CMD:energy(playerid,params[])
{
    new 
hungerUser[playerid][USER_HUNGER]; 
    new 
thirstUser[playerid][USER_THIRST]; 
    new 
string[60],stats[60];
       
    
format(stringsizeof string"Голод: %s\nЖажда: %s"hungerthirst); 
    
format(statssizeof stats"%s"string);
    
ShowPlayerDialog(playerid,6,DIALOG_STYLE_MSGBOX,"Энергия",string,"Ok","");
    return 
1;


Вы можете сделать больше функций, таких как таймер каждые 10 минут, что бы уменьшать голод и жажду. И когда у вас мало энергии вы теряете часть здоровья и т.д.


SJplayer M
Модератор
Модератор
Аватара
SJplayer M
Модератор
Модератор
Сообщения: 196
Зарегистрирован: 25 мая 2013
С нами: 10 лет 10 месяцев

#2 SJplayer » 18 января 2014, 10:34

Здорово, жаль я в SQL не шарю

Дим M
Администратор
Администратор
Аватара
Дим M
Администратор
Администратор
Сообщения: 1608
Зарегистрирован: 5 апреля 2013
С нами: 10 лет 11 месяцев

#3 Дим » 18 января 2014, 10:53

SJplayer писал(а):Здорово, жаль я в SQL не шарю
А что мешает переделать, например на ini :?:
[center]i love you [s]mxIni[/s] Mysql[/center]

Layk M
Прапорщик
Прапорщик
Аватара
Layk M
Прапорщик
Прапорщик
Сообщения: 170
Зарегистрирован: 4 июня 2013
С нами: 10 лет 9 месяцев

#4 Layk » 18 января 2014, 20:29

Дим писал(а):А что мешает переделать, например на ini :?:
Переделайте пожалуста :oops:
Изображение

LILU M
Подполковник
Подполковник
Аватара
LILU M
Подполковник
Подполковник
Сообщения: 468
Зарегистрирован: 5 апреля 2013
С нами: 10 лет 11 месяцев

#5 LILU » 18 января 2014, 21:15

Layk писал(а):Переделайте пожалуста :oops:
Будет время, попробую


  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Уроки»

Кто сейчас на форуме (по активности за 5 минут)

Сейчас этот раздел просматривают: 3 гостя