[Статья] Способ хранения переменных для каждого игрока

Сергей68

Неуместный юмор
Сообщения
420
Реакции
377
все любители Pawn на SA:MP
Я то думаю от куда ноги то растут 🌚 , я тоже изначально применял все знания самповского Pawn в Source, но с каждым разом сталкивался с проблемами в плане оптимизации и т.д, по сути то язык один - убогий, но написание и функционирование другое.

Оффтоп
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
Больше всего мне нравится вот это предложение в первоисточнике: Note that even though enum structs are actually arrays, for the most part they cannot be used as arrays.
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #23
Можно всё это и так реализовать на предыдущих версиях SM:
C-подобный:
enum
{
    T_Coin,
    T_Money,
    T_Gold,

    T_Total
};

int
    iValues[MAXPLAYERS+1][T_Total];
char
    sValue[MAXPLAYERS+1][MAX_NAME_LENGTH];

stock void PrintValues(int client)
{
    PrintToChat(client, "Твои монеты, %s: %i", sValue[client], iValues[client][T_Coin]);
    PrintToChat(client, "Твои деньги, %s: %i", sValue[client], iValues[client][T_Money]);
    PrintToChat(client, "Твоё золото, %s: %i", sValue[client], iValues[client][T_Name]);
}
Сообщения автоматически склеены:

Rabb1t, какие-то в 1.10 ввели, которые в 1.11 вывели.
не совсем. старый enum больше подходит для перечислений (для чего он изначально и создан в нормальных языках). Т.е. просто навешивал обертку поверх инта.
Твоя реализация это по сути просто именование индексов, аля "0 это Coin, 1 это Money", не более того.
Новый enum уже больше уходит в ооп и походит на struct из си. Т.е. такой мини-класс, который имеет различные свойства различных типов, и если тут верно написано https://hlmod.ru/threads/statja-sposob-xranenija-peremennyx-dlja-kazhdogo-igroka.53039/#post-471652 то и методы для работы с ними.
Не проще ли тогда использовать такую структуру?
C-подобный:
enum struct UnusVars
{
    int Coins[MAXPLAYERS+1];
    int Money[MAXPLAYERS+1];
    // ...

    void AddCoin(int iCount, int iIndex = -1)
    {
        int i;
        while(i++ < MaxClients)
            if((iIndex != -1 && i == iIndex) || iIndex == -1)
                this.Coins[i] += iCount;
    }

    void AddMoney(int iCount, int iIndex = -1)
    {
        int i;
        while(i++ < MaxClients)
            if((iIndex != -1 && i == iIndex) || iIndex == -1)
                this.Money[i] += iCount;
    }
}
а тут смотря с какой стороны посмотреть.
Если со стороны ооп то это бред, ибо в "классе" хранятся все его объекты и придется создавать его экземпляр как синглтон чтобы изменять его состояние.
C:
UnusVars ClientsData;
ClientsData.AddCoin(1, iClient);
ну тоже не очень коротко.
Со стороны процедурки - нам эта структура вообще не нужна, а просто 2 массива и 2 функции.
И по-моему цикл не будет обрабатывать игрока в последнем слоте.
и условие можно упростить до if(i == iIndex || iIndex == -1)

насчет ошибок на новом см - они реально были, но уже не помню в каком кейсе.


но тут возникает вопросик. зачем тогда методмапы? тоже самое но без свойств?
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #24
Да, почитал доку. методы есть.
Получается с точки зрения эстетики самое красивое применение enum struct в данном контексте:
Есть enum struct Player, у него есть свойства (при чем некоторые из них тоже enum struct), все индексы игрока мы сразу преобразуем в объект (ну макросом например) и через его методы изменяем свойства, тогда не будет [client], который мозолит вам глаза.
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #25
Больше всего мне нравится вот это предложение в первоисточнике: Note that even though enum structs are actually arrays, for the most part they cannot be used as arrays.
скорее всего имелось ввиду что с ними нельзя работать как с массивами (обращаться по индексу к свойствам, добавлять, удалять элементы), а работать как с объектами.
 

rejchev

менеджер клоунов
Сообщения
1,669
Реакции
1,291
И по-моему цикл не будет обрабатывать игрока в последнем слоте.
Там постфиксный инкремент, он разве что с нулевой ячейкой не считается


но тут возникает вопросик. зачем тогда методмапы? тоже самое но без свойств?
Ну там тип "наследование" имеется. Больше смахивает на два недостроенных дома на пару со структурами
 

Kruzya

Участник
Сообщения
12,970
Реакции
10,914
  • Команда форума
  • #27
Пусть сначала свои оф инклуды пофиксят, перед тем как вводить эти стракты.
В 3 часа ночи подумал такой "а дай пофикшу билд в тревисе". Ага, конечно, пофиксил.
1590966684371.png
А все потому что у них у самих в инклудах SM до сих пор можно нарваться на enum в качестве индексатора массива:
https://github.com/alliedmodders/so...15de/plugins/include/tf2_stocks.inc#L309-L351
Что, внезапно, приводит к падающему билду:
1590966806053.png

В итоге версии, которым разрешено падать (ибо "легаси") - собираются, а стабильная и dev - нихрена. 👍
Веселуха, одним словом.
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
скорее всего имелось ввиду что с ними нельзя работать как с массивами (обращаться по индексу к свойствам, добавлять, удалять элементы), а работать как с объектами.
я про индекс массива понял
 

JDW

Мы открываем бизнес
Сообщения
376
Реакции
325
Да, ты прав, что в памяти от этого ничего не изменится (я не уверен, может на капельку повлияет в худшую сторону), но все-таки так удобнее для меня ;)
Точно могу сказать, что так принято на Pawno (только там юзался двумерный массив с енумом), который в SA:MP используется. Там тоже можно создавать массивы переменных, но людям удобнее вот так.
Сообщения автоматически склеены:


Да, это я прекрасно понимаю, просто мне однажды кто-то опытный посоветовал делать MAXPLAYERS+1, чтобы не было ошибок.
Все-таки мысленно мы понимаем, что будем использовать только 64.
Да, способ точно не мой) подправлю. Дело в том, что этот способ был найден уже довольно давно, когда начали появляться варнинги об удалении этой возможности в 1.11 (как видим, нас обманули =( ). Я решил им поделиться, потому что он правда выглядит приятнее.


Да, спасибо за идею, дополню. Просто если бы удалили способ с двумерным массивом и enum, то это была бы единственная такая альтернатива.
Не знаю, я каждый раз когда пробовал делать двумерные массивы такие с enum, то выдавал варнинг. Загуглил решение и начал писать на таких структурах .-.
А на 1.11 я еще даже ничего не делал)
Как по мне, то, что можно делать на обычном павне(создавать структуры в перечислениях), то это полное извращение и вырви глаз. Перечисления не для этого придумали и когда я вижу код, где перечисления используются, как структура ака структуры си(enum struct не в счёт, хотя все это просто синтаксический сахар). Ребята, не надо такой фигнёй страдать, используйте вещи только для того, для чего изначально они создавались
 
Сверху Снизу