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

    Статус
    Оффлайн
    Регистрация
    20.10.2013
    Сообщений
    40
    Репутация:
    1 ±

    set&getData без учета string,float etc...

    Всем привет!
    Не знал как назвать тему так что заранее прошу прощения.
    Я решил сделать функции наподобие setElementData, getElementData (аля MTA), но столкнулся проблемой.
    Не знаю как объяснить, попытаюсь объяснить кодом
    У меня есть enum для игрока с разными переменными.
    PHP код:
    enum player_data {
        
    Name[MAX_PLAYER_NAME+1],//string
        
    Pass[32],//string
        
    Ip[16],//string
        
    bool:Logged,//bool
        
    Float:X,//Float
        
    Float:Y,//Float
        
    Float:Z,//Float
        
    Level//Integer
    }
    new 
    pData[MAX_PLAYERS][player_data]; 
    И я к ним "сделал" универсальные функции
    PHP код:
    stock _setData(playeriddatavalue) {
        if (
    pData[playerid][data]) {// если data имеются в enum
            
    pData[playerid][data] = value;//меняем значение data
        
    }
    }

    stock _getData(playeriddata) {
        if (
    pData[playerid][data]) {// если data имеются в enum
            
    return pData[playerid][data];// возвращаем data
        
    }

    Я знаю что функции сейчас не будут работать ибо функции будут работают только с integer данными т.е номерными.
    PHP код:
    _setData(playeridLevel2)//меняем игроку лвл
    _getData(playeridLevel)//узнаем лвл игрока 
    Есть ли способ заставить работать эти функции и с другими видами? я имею ввиду (integer, strin, float, bool и т.д).
    PHP код:
    _setData(playeridLoggedtrue)//
    _getData(playeridLogged)//
    //etc 
    p.s возможно кто то спросить зачем это мне, мне так удобней.
    Заранее спасибо за ответ.

  2. #2
    Аватар для Daniel_Cortez
    new fuck_logic[0] = EOS;

    Статус
    Онлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    1,760
    Репутация:
    2252 ±
    Накидал простой пример:
    PHP код:
    #include <a_samp>

    const PL_NAME_SIZE MAX_PLAYER_NAME 1;
    const 
    PL_PASS_HASH_SIZE 64 1;
    enum e_PLAYER_INFO
    {
        
    plName[PL_NAME_SIZE],
        
    plPassHash[PL_PASS_HASH_SIZE],
        
    bool:plLoginStatus,
        
    plLevel,
        
    plMoney,
        
    plAdminLevel,
        
    Float:plXFloat:plYFloat:plZ
    };
    new 
    player_info[MAX_PLAYERS][e_PLAYER_INFO];

    PrintPlayerInfo(playerid)
    {
        
    printf("Name: %s"player_info[playerid][plName]);
        
    printf("PassHash: %s"player_info[playerid][plPassHash]);
        static const 
    bool_strs[2][] = {{"false"}, {"true"}};
        
    printf("LoginStatus: %s",bool_strs[!!player_info[playerid][plLoginStatus]]);
        
    printf("Level: %d"player_info[playerid][plLevel]);
        
    printf("Money: %d"player_info[playerid][plMoney]);
        
    printf("AdminLevel: %d"player_info[playerid][plAdminLevel]);
        
    printf("X: %f"player_info[playerid][plX]);
        
    printf("Y: %f"player_info[playerid][plY]);
        
    printf("Z: %f"player_info[playerid][plZ]);
    }

    SetPlayerField(playeride_PLAYER_INFO:field, {_Floatbool}:value)
        
    player_info[playerid][field] = value;

    SetPlayerFieldString(playeride_PLAYER_INFO:field, const value[], field_size)
        
    strmid(player_info[playerid][field], value0strlen(value), field_size);

    main()
    {
        
    SetPlayerFieldString(0plName"Daniel_Cortez"PL_NAME_SIZE);
        
    SetPlayerField(0plLoginStatustrue);
        
    SetPlayerField(0plLevel20);
        
    SetPlayerField(0plMoneyfalse);
        
    SetPlayerField(0plAdminLevel9001);
        
    SetPlayerField(0plX2000.0);
        
    SetPlayerField(0plY30.0);
        
    SetPlayerField(0plZ100);
        
    PrintPlayerInfo(0);

    Обратите внимание: нельзя сделать один и тот же аргумент под одиночное значение и массив, поэтому я сделал отдельную функцию для сохранения строк.
    Функции для получения значений, надеюсь, сами доделаете.

    И да, в функции SetPlayerField нельзя проверить тег value, поэтому в поле с целочисленным тегом можно передать true или false, а в вещественное поле нечаянно записать целое число. Присмотритесь к записи в поля plMoney и plZ в функции main: я специально ошибся, чтобы показать, что компилятор не заметит никаких ошибок и компилирует код без единого варнинга.

    UPD: Попробовал сам сделать функцию GetPlayerField - оказалось не так просто, как могло показаться. Возможно, стоит разделить функции (Get/Set)PlayerField на 6 функций: (Get/Set)PlayerField(Int/Float/Bool). Или каждый раз при использовании GetPlayerField перезаписывать тег возвращаемого значения, если нужно получить bool или Float.
    Проще пользоваться массивами, как все нормальные люди - заодно не будет проблем с путаницей тегов значений в SetPlayerValue.
    Индивидуально в PM и Skype по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).
    SA-MP 0.4 is a lie

  3. Пользователь сказал cпасибо:
    Jeff_Monson (26.12.2015)
  4. #3
    Аватар для VVWVV
    Проверенный

    Статус
    Оффлайн
    Регистрация
    09.07.2015
    Сообщений
    657
    Репутация:
    314 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Возможно, стоит разделить функции (Get/Set)PlayerField на 6 функций: (Get/Set)PlayerField(Int/Float/Bool).
    Можно разделять теги с помощью функции tagof.

  5. #4
    Аватар для Daniel_Cortez
    new fuck_logic[0] = EOS;

    Статус
    Онлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    1,760
    Репутация:
    2252 ±
    Цитата Сообщение от VVWVV Посмотреть сообщение
    Можно разделять теги с помощью функции tagof.
    В курсе, я даже как-то делал урок на эту тему: http://pro-pawn.ru/showthread.php?12257
    И это не функция, а оператор, раз уж на то пошло.

    Ок, вот решение с GetPlayerField (к слову, оператор tagof вообще не пригодился):
    PHP код:
    #include <a_samp>


    const PL_NAME_SIZE MAX_PLAYER_NAME 1;
    const 
    PL_PASS_HASH_SIZE 64 1;
    enum e_PLAYER_INFO
    {
        
    plName[PL_NAME_SIZE],
        
    plPassHash[PL_PASS_HASH_SIZE],
        
    bool:plLoginStatus,
        
    plLevel,
        
    plMoney,
        
    plAdminLevel,
        
    Float:plXFloat:plYFloat:plZ
    };
    new 
    player_info[MAX_PLAYERS][e_PLAYER_INFO];


    GetPlayerField(playeride_PLAYER_INFO:field, &{_Floatbool}:value)
    {
        
    value player_info[playerid][field];
    }

    SetPlayerField(playeride_PLAYER_INFO:field, {_Floatbool}:value)
    {
        
    player_info[playerid][field] = value;
    }

    GetPlayerFieldString(playerid,e_PLAYER_INFO:fieldbuf[],buf_size sizeof(buf))
    {
        
    buf[0] = '\0'strcat(bufplayer_info[playerid][field], buf_size);
    }

    SetPlayerFieldString(playeride_PLAYER_INFO:field, const value[], field_size)
    {
        
    strmid(player_info[playerid][field], value0strlen(value), field_size);
    }


    PrintPlayerInfo(playerid)
    {
        new 
    int_valuefloat_valuebool_value;
        new 
    array_value[128];
        static const 
    bool_strs[2][] = {{"false"}, {"true"}};
        
    GetPlayerFieldString(playeridplNamearray_value);
        
    printf("Name: %s"array_value);
        
    GetPlayerFieldString(playeridplPassHasharray_value);
        
    printf("PassHash: %s"array_value);
        
    GetPlayerField(playeridplLoginStatusbool_value);
        
    printf("LoginStatus: %s"bool_strs[!!bool_value]);
        
    GetPlayerField(playeridplLevelint_value);
        
    printf("Level: %d"int_value);
        
    GetPlayerField(playeridplMoneyint_value);
        
    printf("Money: %d"int_value);
        
    GetPlayerField(playeridplAdminLevelint_value);
        
    printf("AdminLevel: %d"int_value);
        
    GetPlayerField(playeridplXfloat_value);
        
    printf("X: %f"float_value);
        
    GetPlayerField(playeridplYfloat_value);
        
    printf("Y: %f"float_value);
        
    GetPlayerField(playeridplZfloat_value);
        
    printf("Z: %f"float_value);
    }


    main()
    {
        
    SetPlayerFieldString(0plName"Daniel_Cortez"PL_NAME_SIZE);
        new 
    hash[PL_PASS_HASH_SIZE];
        
    format(hashsizeof(hash), "%x"0xDC);
        
    SetPlayerFieldString(0plPassHashhashPL_NAME_SIZE);
        
    SetPlayerField(0plLoginStatustrue);
        
    SetPlayerField(0plLevel20);
        
    SetPlayerField(0plMoneyfalse);
        
    SetPlayerField(0plAdminLevel9001);
        
    SetPlayerField(0plX2000.0);
        
    SetPlayerField(0plY30.0);
        
    SetPlayerField(0plZ100);
        
    PrintPlayerInfo(0);

    В Pawn нельзя сделать функцию, которая может вернуть значение нескольких типов, поэтому пришлось сделать возврат по ссылке.
    К тому же, такой подход с установкой и получением значений с помощью функций может отразиться на производительности и повысить использование стека.
    Правда, иногда этот подход может пригодиться: например, если массив player_info вынесен в инклуд и объявлен с атрибутом static, чтобы нельзя было получить к нему доступ напрямую из других исходных файлов. Но такое бывает редко, если бывает вообще (лично я ни разу не видел таких модов).
    Индивидуально в PM и Skype по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).
    SA-MP 0.4 is a lie

  6. Пользователь сказал cпасибо:
    Jeff_Monson (26.12.2015)
  7. #5
    Аватар для VVWVV
    Проверенный

    Статус
    Оффлайн
    Регистрация
    09.07.2015
    Сообщений
    657
    Репутация:
    314 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    В курсе, я даже как-то делал урок на эту тему: http://pro-pawn.ru/showthread.php?12257
    И это не функция, а оператор, раз уж на то пошло.
    Да, также, как и оператор return и т.п.
    Как вы и сказали, что лучше будет:
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Возможно, стоит разделить функции (Get/Set)PlayerField на 6 функций: (Get/Set)PlayerField(Int/Float/Bool)

  8. #6
    Аватар для $continue$
    Заблокирован

    Статус
    Оффлайн
    Регистрация
    02.08.2014
    Адрес
    г. Киров (aka Вятка)
    Сообщений
    1,466
    Репутация:
    265 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    В Pawn нельзя сделать функцию, которая может вернуть значение нескольких типов, поэтому пришлось сделать возврат по ссылке.
    Не только в Pawn, в С/C++ такая же ситуация. Без ссылок либо указателей нельзя вернуть более 1 значения (По крайней мере я такого "чуда" пока что не видел)
    Ах, да можно еще через структуру.

  9. #7
    Аватар для Daniel_Cortez
    new fuck_logic[0] = EOS;

    Статус
    Онлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    1,760
    Репутация:
    2252 ±
    Цитата Сообщение от $continue$ Посмотреть сообщение
    Не только в Pawn, в С/C++ такая же ситуация. Без ссылок либо указателей нельзя вернуть более 1 значения (По крайней мере я такого "чуда" пока что не видел)
    Ах, да можно еще через структуру.
    В C++ хотя бы есть перегрузка функций. В Pawn для такого эффекта приходится танцевать с бубном (ссылка в моём посте выше) и жертвовать производительностью.
    Индивидуально в PM и Skype по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).
    SA-MP 0.4 is a lie

  10. Пользователь сказал cпасибо:
    Jeff_Monson (26.12.2015)
  11. #8
    Аватар для Jeff_Monson
    Пользователь

    Статус
    Оффлайн
    Регистрация
    20.10.2013
    Сообщений
    40
    Репутация:
    1 ±
    Спасибо большое, дело в том что, все это будет лежать в player.inc а использоваться в самом моде.
    Проще пользоваться массивами, как все нормальные люди - заодно не будет проблем с путаницей тегов значений в SetPlayerValue.
    Ну видать я не нормальный, а если честно да я знаю, я подметил что мне так более удобней, путаница будет в том случай если мод попадет третьим лицам.

  12. #9
    Аватар для Daniel_Cortez
    new fuck_logic[0] = EOS;

    Статус
    Онлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    1,760
    Репутация:
    2252 ±
    Цитата Сообщение от Jeff_Monson Посмотреть сообщение
    путаница будет в том случай если мод попадет третьим лицам.
    Хотите сказать, вы никогда не совершаете ошибок? Ну-ну...
    Индивидуально в PM и Skype по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).
    SA-MP 0.4 is a lie

  13. Пользователь сказал cпасибо:
    Jeff_Monson (26.12.2015)
  14. #10
    Аватар для Jeff_Monson
    Пользователь

    Статус
    Оффлайн
    Регистрация
    20.10.2013
    Сообщений
    40
    Репутация:
    1 ±
    Совершал, если заметить в начале темы strin. но путать money с health или же health c pos думаю глупо.
    Хотя совершал) ошибки. именно когда работал с типы данными) но это в прошлом.
    Задам еще один вопрос, дабы не создавать каждый раз тему.
    Мне надо внутри enum создать переменную с 3мя разными значениями.
    PHP код:
    enum player_data {
        ...,
        
    Test[3][MAX_PLAYER_NAME+1]
    };
    new 
    pData[MAX_PLAYERS][player_data];

    main() {
        
    printf("Test 1: %s"pData[0][Test][1]);
        
    printf("Test 2: %s"pData[0][Test][2]);
        
    printf("Test 3: %s"pData[0][Test][3]);

    Вот только дебаг(компилятор) ругается.
    Придется отдельно создавать переменную для таких случай?

 

 

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

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

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

Ваши права

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