Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Показано с 1 по 4 из 4
  1. #1
    Аватар для L0ndl3m
    Пользователь

    Статус
    Оффлайн
    Регистрация
    19.10.2013
    Адрес
    Ярославль
    Сообщений
    1,366
    Репутация:
    774 ±

    Система достижений

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

    Попробуем сделать систему достижений из 3 штук.

    Достижения
    • Вынос мозга
    • Вершина мира
    • Маньяк


    В начало мода, создадим глобально ( то есть ко всем new )
    PHP код:

    const
        
    MAX_ACHIEVEMENT_NAME 13,
        
    DIALOG_ACHIEVEMENTS 512,
        
    DIALOG_ACHIEVEMENTS_EXP 1024;

    static const
        
    achievement_names[][MAX_ACHIEVEMENT_NAME] =
        {
            
    "Вынос мозга""Вершина мира""Маньяк"
        
    };

    new
        
    achievement[MAX_PLAYERS],
        
    ach_progress[MAX_PLAYERS][2 char];

    #if !defined BODY_PART_TORSO
    enum
    {
        
    BODY_PART_TORSO 3,
        
    BODY_PART_GROIN,
        
    BODY_PART_LEFT_ARM,
        
    BODY_PART_RIGHT_ARM,
        
    BODY_PART_LEFT_LEG,
        
    BODY_PART_RIGHT_LEG,
        
    BODY_PART_HEAD
    };
    #endif  

    enum(<<= 1)
    {
        
    ACHIEVEMENT_BRAINFUCK 1,
        
    ACHIEVEMENT_TOP_OF_THE_WORLD,
        
    ACHIEVEMENT_MANIAC
    }; 
    Начнём с первого достижения: Вынос мозга.

    Суть достижения заключается в том, чтобы за один сеанс игры убить 5 человек в голову.
    Реализация будет выглядеть так: добавляем в public OnPlayerGiveDamage
    PHP код:
    if(damagedid != INVALID_PLAYER_ID && bodypart == BODY_PART_HEAD)
    {
        
    SetPlayerHealth(damagedid0.0);

        if(((
    achievement[playerid] & ACHIEVEMENT_BRAINFUCK) == 0) && ++ach_progress[playerid]{0} == 5)
        {
            
    UnlockPlayerAchievement(playerid0);
            
    GivePlayerMoney(playerid100000);
            
    SendClientMessage(playerid, -1"Вы получили вознаграждение: {FF0000}$100000");
        }

    Реализация первого достижения готова.

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

    Добавляем в public OnGameModeInit:
    PHP код:
    SetTimer("@__achievement_update"10001); 
    В любое место в моде, можно ко всем public'ам:
    PHP код:
    @__achievement_update();
    @
    __achievement_update()
    {
        new
            
    GetMaxPlayers();

        do
        {
            --
    i;
            if(
    IsPlayerConnected(i) && (== (achievement[i] & ACHIEVEMENT_TOP_OF_THE_WORLD)) && IsPlayerInRangeOfPoint(i2.0, -2432.7881, -1620.0902526.8478))
            {
                
    UnlockPlayerAchievement(i1);
                
    GivePlayerWeapon(i38150);
                
    SendClientMessage(i, -1"Вы получили: {FF0000}150 патронов к оружию Minigun");
            }
        }
        while(
    i);

    Реализация второго достижения готова.

    Приступим к последнему, третьему достижению: Маньяк.
    Суть достижения заключается в том, чтобы убить пятерых игроков лопастями вертолёта.

    Реализуем достижение, добавив в public OnPlayerDeath:
    PHP код:
    if(reason == 50 && killerid != INVALID_PLAYER_ID && ((achievement[killerid] & ACHIEVEMENT_MANIAC) == 0) && ++ach_progress[killerid]{1} == 5)
    {
        
    UnlockPlayerAchievement(killerid2);
        
    SetPlayerHealth(killerid500.0);
        
    SendClientMessage(killerid, -1"Вы получили: {FF0000}500 единиц здоровья.");

    Реализация трёх достижений готова.

    Создадим отдельный сток, который будет показывать какой игрок разблокировал достижение, в любое место скрипта (ко всем stock'ам):
    PHP код:
    stock UnlockPlayerAchievement(const playerid, const id)
    {
        
    achievement[playerid] |= << id;

        static const
            
    fmt_str[] = "• {FF0000}%s (%i){AAAADD} разблокировал достижение: {FF0000}%s";
        
        new
            
    str[sizeof(fmt_str) - MAX_PLAYER_NAME MAX_ACHIEVEMENT_NAME];

        
    GetPlayerName(playeridstrsizeof(str));    

        
    format(strsizeof(str), fmt_strstrplayeridachievement_names[id]);
        
    SendClientMessageToAll(-1str);

    Добавим команду, в которой будет видно, разблокировал ли игрок какое-либо достижение:
    PHP код:
    CMD:achs(playeridparams[]) // if(strcmp(cmdtext, "/achs", true, 5) == 0)
    {
        return 
    ShowPlayerAchievementsDialog(playerid);

    В конец мода, функцию показа диалога:
    PHP код:
    ShowPlayerAchievementsDialog(const playerid)
    {
        static const
            
    fmt_str[] = "\
            1. Вынос мозга [%s{FFFFFF}]\n\
            2. Вершина мира [%s{FFFFFF}]\n\
            3. Маньяк [%s{FFFFFF}]"
    ,
            
    lock_str[][] =
            {
                {
    "{FF0000}Заблокировано"},
                {
    "{00CC00}Разблокировано"}
            };
            
        new
            
    str[(sizeof(fmt_str) - 21) * sizeof(achievement_names)];

        
    format
        
    (
            
    strsizeof(str), fmt_str,
            
    lock_str[(achievement[playerid] & ACHIEVEMENT_BRAINFUCK) != 0],
            
    lock_str[(achievement[playerid] & ACHIEVEMENT_TOP_OF_THE_WORLD) != 0],
            
    lock_str[(achievement[playerid] & ACHIEVEMENT_MANIAC) != 0]
        );
        
        return 
    ShowPlayerDialog(playeridDIALOG_ACHIEVEMENTSDIALOG_STYLE_LIST"Список достижений"str"Выбрать""Закрыть");

    Добавим распознавание диалогов, в public OnDialogResponse:
    PHP код:
    if(dialogid == DIALOG_ACHIEVEMENTS// case DIALOG_ACHIEVEMENTS:
    {
        if(
    response == 0)
            return 
    1;

        static const
            
    achievement_explans[][] =
            {
                
    "Цель: Убить 5 игроков в голову за один сеанс игры\nНаграда: {FF0000}$100000",
                
    "Цель: Залезть на вершину горы чиллиад (это самая высокая точка на карте)\nНаграда: {FF0000}150 патронов к оружию Minigun",
                
    "Цель: Убить 5 игроков лопастями вертолёта за один сеанс игры\nНаграда: {FF0000}500 единиц здоровья"
            
    };

        return 
    ShowPlayerDialog(playeridDIALOG_ACHIEVEMENTS_EXPDIALOG_STYLE_MSGBOX"Описание достижения"achievement_explans[listitem], "Закрыть""Назад");
    }

    if(
    dialogid == DIALOG_ACHIEVEMENTS_EXP// case DIALOG_ACHIEVEMENTS_EXP:
    {
        return (
    response == 0) ? (ShowPlayerAchievementsDialog(playerid)) : (1);

    С "игровой" частью мы справились. Осталось сделать сохранение достижении игрока, добавим в любое место в моде (ко всем stock'ам):
    PHP код:
    stock SavePlayerAchievements(const playerid)
    {
        if(
    PlayerInfo[playerid][pLogged] == 0)
            return;
        
    // Здесь вы выставляете свою проверку на логин игрока,
        // если игрок не залогинен его достижения не сохранятся

        
    static const
            
    acc_str[] = "AchievementProgress/%s.ini";

        new
            
    str[sizeof(acc_str) - MAX_PLAYER_NAME];

        
    GetPlayerName(playeridstrsizeof(str));
        
    format(strsizeof(str), acc_strstr);

        new
            
    Filefile fopen(strio_write);
        
        if(
    file == File0)
            return;

        
    valstr(strachievement[playerid]);

        
    fwrite(filestr);

        
    fclose(file);
    }

    stock LoadPlayerAchievements(const playerid)
    {
        static const
            
    acc_str[] = "AchievementProgress/%s.ini";

        new
            
    str[sizeof(acc_str) - MAX_PLAYER_NAME];

        
    GetPlayerName(playeridstrsizeof(str));
        
    format(strsizeof(str), acc_strstr);

        if(
    fexist(str) == 0)
            return;

        new
            
    Filefile fopen(strio_read);

        if(
    file == File0)
            return;

        
    fread(filestr);

        
    achievement[playerid] = strval(str);

        
    fclose(file);

    Добавляем сохранение достижений в public OnPlayerDisconnect:
    PHP код:
    SavePlayerAchievements(playerid);

    ach_progress[playerid]{0} = 0;
    ach_progress[playerid]{1} = 0
    Добавляем загрузку достижений туда, где у вас загружается аккаунт (например OnPlayerLogin):
    PHP код:
    LoadPlayerAchievements(playerid); 
    В общем-то и всё.

     Скриншоты







    Автор: L0ndl3m

    Специально для: Pro-Pawn.Ru


    Копирование данной статьи без разрешения автора запрещено!
    Последний раз редактировалось L0ndl3m; 17.01.2020 в 14:51.

  2. Пользователь сказал cпасибо:
    heralt (13.03.2015)
  3. #2
    Аватар для somebodies
    Пользователь

    Статус
    Оффлайн
    Регистрация
    03.01.2017
    Сообщений
    30
    Репутация:
    0 ±

    Проблема с системой

    Приветствую! Проблема следующая:
    Абсолютно никаким способом не открывается достижение под ID 0 , т.е "вынос мозга". UnlockPlayerAchievement(playerid, 0); не помогает в данном случае. (причем остальные достижения с ID > 0 открываются без проблем)

    Также имеется маленькая проблема с сохранением, в .ini файл сохраняется лишь одна цифра, но достижений, как минимум, 3. где-то здесь кроется неполадка, как мне кажется.


    какие могли возникнуть проблемы? код не изменял

    заранее благодарю за помощь!
    Последний раз редактировалось DeimoS; 31.05.2017 в 19:13. Причина: Перенёс сообщения из раздела с вопросами

  4. #3
    Аватар для ziggi
    Проверенный

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    1,181
    Репутация:
    790 ±
    Наверное, функция должна начинаться так:
    PHP код:
    stock UnlockPlayerAchievement(const playerid, const id)
    {
        
    achievement[playerid] |= << id
    Последний раз редактировалось DeimoS; 31.05.2017 в 19:13. Причина: Перенёс сообщения из раздела с вопросами

  5. Пользователь сказал cпасибо:
    L0ndl3m (01.06.2017)
  6. #4
    Аватар для somebodies
    Пользователь

    Статус
    Оффлайн
    Регистрация
    03.01.2017
    Сообщений
    30
    Репутация:
    0 ±
    Цитата Сообщение от ziggi Посмотреть сообщение
    Наверное, функция должна начинаться так:
    PHP код:
    stock UnlockPlayerAchievement(const playerid, const id)
    {
        
    achievement[playerid] |= << id
    P.S. Почему ты не написал в той теме об этом?

    Теперь все работает. Проблема с сохранением также решилась каким-то образом.
    Последний раз редактировалось DeimoS; 31.05.2017 в 19:13. Причина: Перенёс сообщения из раздела с вопросами

 

 

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •