Добро пожаловать на 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
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Накидал простой пример:
    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.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

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

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

  5. #4
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от 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, чтобы нельзя было получить к нему доступ напрямую из других исходных файлов. Но такое бывает редко, если бывает вообще (лично я ни разу не видел таких модов).
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

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

    Статус
    Оффлайн
    Регистрация
    09.07.2015
    Сообщений
    731
    Репутация:
    353 ±
    Цитата Сообщение от 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,487
    Репутация:
    276 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    В Pawn нельзя сделать функцию, которая может вернуть значение нескольких типов, поэтому пришлось сделать возврат по ссылке.
    Не только в Pawn, в С/C++ такая же ситуация. Без ссылок либо указателей нельзя вернуть более 1 значения (По крайней мере я такого "чуда" пока что не видел)
    Ах, да можно еще через структуру.
    Value your freedom or you will lose it, teaches history. "Don't bother us with politics," respond those who don't want to learn. (c) Richard Stallman

  9. #7
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

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

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

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

  12. #9
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от Jeff_Monson Посмотреть сообщение
    путаница будет в том случай если мод попадет третьим лицам.
    Хотите сказать, вы никогда не совершаете ошибок? Ну-ну...
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  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)

Ваши права

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