Система статистики игроков в Pawn

Активный
Статус
Сообщения
516
Лайки
32

8

месяц на сайте

В этом руководстве разберем создание полноценной системы статистики для игроков с сохранением в MySQL и отображением через диалоги.

Структура данных статистики

Код:
enum PlayerStats
{
    pKills,
    pDeaths,
    pScore,
    pMoney,
    pLevel,
    pExperience,
    pPlayTime,
    pWins,
    pLosses,
    Float:pKD
}

new PlayerStat[MAX_PLAYERS][PlayerStats];

Инициализация статистики

Код:
LoadPlayerStats(playerid)
{
    new query[256], name[MAX_PLAYER_NAME];
    GetPlayerName(playerid, name, sizeof(name));
    
    format(query, sizeof(query), "SELECT * FROM player_stats WHERE name = '%e'", name);
    mysql_query(g_SQL, query);
    mysql_store_result();
    
    if(mysql_num_rows() > 0)
    {
        PlayerStat[playerid][pKills] = mysql_fetch_int();
        PlayerStat[playerid][pDeaths] = mysql_fetch_int();
        PlayerStat[playerid][pScore] = mysql_fetch_int();
        PlayerStat[playerid][pMoney] = mysql_fetch_int();
        PlayerStat[playerid][pLevel] = mysql_fetch_int();
        PlayerStat[playerid][pExperience] = mysql_fetch_int();
        PlayerStat[playerid][pPlayTime] = mysql_fetch_int();
        PlayerStat[playerid][pWins] = mysql_fetch_int();
        PlayerStat[playerid][pLosses] = mysql_fetch_int();
        
        if(PlayerStat[playerid][pDeaths] > 0)
        {
            PlayerStat[playerid][pKD] = float(PlayerStat[playerid][pKills]) / float(PlayerStat[playerid][pDeaths]);
        }
        else
        {
            PlayerStat[playerid][pKD] = float(PlayerStat[playerid][pKills]);
        }
    }
    else
    {
        format(query, sizeof(query), "INSERT INTO player_stats (name) VALUES ('%e')", name);
        mysql_query(g_SQL, query);
    }
    
    mysql_free_result();
    return 1;
}

Обновление статистики при убийстве

Код:
public OnPlayerDeath(playerid, killerid, reason)
{
    if(killerid != INVALID_PLAYER_ID)
    {
        PlayerStat[killerid][pKills]++;
        PlayerStat[killerid][pScore] += 2;
        PlayerStat[killerid][pExperience] += 50;
        
        if(PlayerStat[killerid][pDeaths] > 0)
        {
            PlayerStat[killerid][pKD] = float(PlayerStat[killerid][pKills]) / float(PlayerStat[killerid][pDeaths]);
        }
        else
        {
            PlayerStat[killerid][pKD] = float(PlayerStat[killerid][pKills]);
        }
        
        UpdatePlayerStats(killerid);
    }
    
    PlayerStat[playerid][pDeaths]++;
    PlayerStat[playerid][pScore]--;
    
    if(PlayerStat[playerid][pDeaths] > 0)
    {
        PlayerStat[playerid][pKD] = float(PlayerStat[playerid][pKills]) / float(PlayerStat[playerid][pDeaths]);
    }
    
    UpdatePlayerStats(playerid);
    return 1;
}

Сохранение статистики

Код:
UpdatePlayerStats(playerid)
{
    new query[512], name[MAX_PLAYER_NAME];
    GetPlayerName(playerid, name, sizeof(name));
    
    format(query, sizeof(query), 
        "UPDATE player_stats SET kills = %d, deaths = %d, score = %d, money = %d, level = %d, experience = %d, playtime = %d, wins = %d, losses = %d WHERE name = '%e'",
        PlayerStat[playerid][pKills],
        PlayerStat[playerid][pDeaths],
        PlayerStat[playerid][pScore],
        PlayerStat[playerid][pMoney],
        PlayerStat[playerid][pLevel],
        PlayerStat[playerid][pExperience],
        PlayerStat[playerid][pPlayTime],
        PlayerStat[playerid][pWins],
        PlayerStat[playerid][pLosses],
        name
    );
    
    mysql_query(g_SQL, query);
    return 1;
}

Команда просмотра статистики

Код:
CMD:stats(playerid, params[])
{
    new targetid = playerid;
    if(!isnull(params))
    {
        targetid = strval(params);
        if(!IsPlayerConnected(targetid))
        {
            SendClientMessage(playerid, -1, "Игрок не найден");
            return 1;
        }
    }
    
    new string[512], name[MAX_PLAYER_NAME];
    GetPlayerName(targetid, name, sizeof(name));
    
    format(string, sizeof(string),
        "Статистика игрока: %s\n\n\
        Убийств: %d\n\
        Смертей: %d\n\
        K/D: %.2f\n\
        Очки: %d\n\
        Уровень: %d\n\
        Опыт: %d\n\
        Время игры: %d минут\n\
        Побед: %d\n\
        Поражений: %d",
        name,
        PlayerStat[targetid][pKills],
        PlayerStat[targetid][pDeaths],
        PlayerStat[targetid][pKD],
        PlayerStat[targetid][pScore],
        PlayerStat[targetid][pLevel],
        PlayerStat[targetid][pExperience],
        PlayerStat[targetid][pPlayTime],
        PlayerStat[targetid][pWins],
        PlayerStat[targetid][pLosses]
    );
    
    ShowPlayerDialog(playerid, DIALOG_STATS, DIALOG_STYLE_MSGBOX, "Статистика", string, "Закрыть", "");
    return 1;
}

Система опыта и уровней

Код:
AddPlayerExperience(playerid, amount)
{
    PlayerStat[playerid][pExperience] += amount;
    
    new requiredExp = PlayerStat[playerid][pLevel] * 1000;
    if(PlayerStat[playerid][pExperience] >= requiredExp)
    {
        PlayerStat[playerid][pLevel]++;
        PlayerStat[playerid][pExperience] = 0;
        
        new string[128], name[MAX_PLAYER_NAME];
        GetPlayerName(playerid, name, sizeof(name));
        format(string, sizeof(string), "Поздравляем! %s достиг уровня %d!", name, PlayerStat[playerid][pLevel]);
        SendClientMessageToAll(-1, string);
        
        GivePlayerMoney(playerid, PlayerStat[playerid][pLevel] * 1000);
    }
    
    UpdatePlayerStats(playerid);
    return 1;
}

Отслеживание времени игры

Код:
new PlayerConnectTime[MAX_PLAYERS];

public OnPlayerConnect(playerid)
{
    PlayerConnectTime[playerid] = gettime();
    LoadPlayerStats(playerid);
    return 1;
}

public OnPlayerDisconnect(playerid, reason)
{
    new playTime = gettime() - PlayerConnectTime[playerid];
    PlayerStat[playerid][pPlayTime] += playTime / 60;
    UpdatePlayerStats(playerid);
    return 1;
}

Топ игроков

Код:
CMD:top(playerid, params[])
{
    new query[256];
    format(query, sizeof(query), "SELECT name, kills FROM player_stats ORDER BY kills DESC LIMIT 10");
    mysql_query(g_SQL, query);
    mysql_store_result();
    
    new string[512] = "Топ 10 игроков по убийствам:\n\n";
    new row[2], count = 1;
    
    while(mysql_fetch_row(query))
    {
        mysql_fetch_field_row(row[0], "name");
        mysql_fetch_field_row(row[1], "kills");
        format(string, sizeof(string), "%s%d. %s - %s убийств\n", string, count, row[0], row[1]);
        count++;
    }
    
    mysql_free_result();
    ShowPlayerDialog(playerid, DIALOG_TOP, DIALOG_STYLE_MSGBOX, "Топ игроков", string, "Закрыть", "");
    return 1;
}

Создание таблицы в MySQL

Код:
CREATE TABLE IF NOT EXISTS player_stats (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(24) UNIQUE,
    kills INT DEFAULT 0,
    deaths INT DEFAULT 0,
    score INT DEFAULT 0,
    money INT DEFAULT 0,
    level INT DEFAULT 1,
    experience INT DEFAULT 0,
    playtime INT DEFAULT 0,
    wins INT DEFAULT 0,
    losses INT DEFAULT 0
);

Эта система предоставляет полный функционал для отслеживания статистики игроков с сохранением в базе данных и удобным отображением через диалоги.
 

1 человек читают эту тему (Всего: 1, Пользователей: 0, Гостей: 1)

Сверху