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

Nico Yazawa

Бывший MrChester =(
Сообщения
326
Реакции
303
Всем привет!
Решил заняться делом и поделиться своим опытом хранения переменных для каждого игрока.

Вступление
Для начала, хотел бы объяснить, что это и как вообще.
Иногда, в плагинах приходится хранить переменные, которые для каждого игрока будут свои.
Возьмем, к примеру, монеты. У каждого игрока это свое кол-во, значит надо создать 64 таких переменных. В каждой будет кол-во монет 1 клиента.

Можно сделать так, как целый массив:
C-подобный:
int coins[MAXPLAYERS+1];

Тогда обращаться к ник мы будем так: (прибавим всем по 1 монетке):
C-подобный:
for(int i = 1; i <= MaxClients; i++)
{
    coins[i] += 1;
}
А представим, что таких переменных будет много, я думаю будет не очень удобно ими управлять.
И я хочу предложить вам мой способ.

Способ, которым я хочу поделиться (источник)
Сначала, создадим что-то вроде структуры:
C-подобный:
enum struct player
{
 
}

Теперь, объявим данную структуру, как глобальную:
C-подобный:
player player_info[MAXPLAYERS + 1];
В данном случае player_info, это название нашей недоструктуры.

Отлично, давайте добавим в player несколько переменных. Это может быть любой тип: от int до Handle.
C-подобный:
enum struct player
{
    int coins;
    int money;
    int gold;
    // И так далее
}
Теперь у нас есть по 3 переменных, на каждого игрока.

Как же к ним обращаться?
Тут все просто, пишем наше название недоструктуры player_info, после в квадратных скобках пишем индекс игрока и через точку нашу переменную:
C-подобный:
PrintToChat(client, "Твои монетки: %i", player_info[client].coins);
PrintToChat(client, "Твои денюжки: %i", player_info[client].money);
PrintToChat(client, "Твоё золото: %i", player_info[client].gold);

Полный гайд об структурах в языке (на англ)

Заключение
Этот способ не является чем-то обязательным в Вашем коде. Кто-то как хочет, так и прогает.
Я лишь предложил способ, которым всегда пользуюсь и которым мне правда удобнее всего.

Буду рад услышать Вашу критику или отзыв, если это Вам реально как-то помогло =)
 
Последнее редактирование:

Сергей68

Неуместный юмор
Сообщения
420
Реакции
377
Если уж делаешь статью с целью обучения юзеров, то раскрывай полностью материал, что можно использовать в enum а что нельзя.
По больше полезной информации, с которой могут столкнуться читающие твою статью.
 

Nico Yazawa

Бывший MrChester =(
Сообщения
326
Реакции
303
Если уж делаешь статью с целью обучения юзеров, то раскрывай полностью материал, что можно использовать в enum а что нельзя.
Я написал, как использовать одну переменную для всех игроков, я сам не знаю, что еще со структурами делать можно .-.
А если ты про обычные енумы, то они такие же, как в си подобных языках.
 

Nico Yazawa

Бывший MrChester =(
Сообщения
326
Реакции
303
Я думаю в той теме все-таки больше вопросов, а тут мануал целый =)
Сообщения автоматически склеены:

Ох, и правда ошибся .-.
Не прочитал, что здесь с серверами связано
Сообщения автоматически склеены:

Перекинули, спасибо!
 
  • Фэйспалм
Реакции: JDW

rejchev

менеджер клоунов
Сообщения
1,669
Реакции
1,291
Больше похоже не на статью, а на локальное достижение (возможно это прозвучит и грубо).
Почитав вступление так и не понял суть...

Если:
Иногда, в плагинах приходится хранить переменные, которые для каждого игрока будут свои.
то причем тут enum struct который явно задаст некую статичную структуру?

Как связаны данные(значения) переменных с обозначенной выше проблемой?
Как массив int coins[MAXPLAYER+1]; стал 64мя переменными типа int?
Возьмем, к примеру, монеты. У каждого игрока это свое кол-во, значит надо создать 64 таких переменных. В каждой будет кол-во монет 1 клиента.


И как вообще такая структура:
C-подобный:
enum struct player
{
    int coins;
    int money;
    int gold;
    // И так далее
}

Решит такую проблему?
Тогда обращаться к ник мы будем так: (прибавим всем по 1 монетке):

C-подобный:
for(int i = 1; i <= MaxClients; i++)
{
    coins[i] += 1;
}

А представим, что таких переменных будет много, я думаю будет не очень удобно ими управлять.
И я хочу предложить вам мой способ.

Если в итоге нам все равно придется обращаться к каждой из них
palka.jpg


Не проще ли тогда использовать такую структуру?
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;
    }
}
 
Последнее редактирование:

Nico Yazawa

Бывший MrChester =(
Сообщения
326
Реакции
303
Как массив int coins[MAXPLAYER+1]; стал 64мя переменными типа int?
Каким чудом ячейки массива int coins[MAXPLAYER+1] стали равными 1 после объявления/инициализации?
Да, не совсем правильно это назвал. У нас занимается 64 ячейки памяти.
То есть ты хочешь сказать, что если int занимает 0, то он ничего не занимает в памяти? (я не утверждаю, просто сам хочу узнать)

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

Не проще ли тогда использовать такую структуру?
А вот такого я не знал, что можно было сделать)
Все-таки я рассмотрел хранение переменных, а функции в этой структуре уже что-то другое.
Сообщения автоматически склеены:

Решит такую проблему?
Это не проблема, а удобство и понимание кода
 
Последнее редактирование:

rejchev

менеджер клоунов
Сообщения
1,669
Реакции
1,291
То есть ты хочешь сказать, что если int занимает 0, то он ничего не занимает в памяти? (я не утверждаю, просто сам хочу узнать)
Вообще речь о присваивании значений, а не выделяемой памяти под тип. Скорей, я просто не понял сути этого:
В каждой будет кол-во монет 1 клиента.
Опустим...


Я показал свой способ делать это. Лично мне так удобнее и приятнее, когда знаю, что информация о игроке находится в одной структуре.
Тогда статья просто утрачивает ценность, т.к. нет конкретных плюсов в данном способе хранения данных.
Если есть своя точка зрения и вы хотите ей поделиться, то должны быть и аргументы, которые могут ее защитить, иначе это больше походит на "о я научился плавать, пойду всем расскажу".
 

Nico Yazawa

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

int coins[MAXPLAYER+1]; // mb MAXPLAYERS ?
>



#define MAXPLAYERS 64
64+1 = 65

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

Kruzya

Участник
Сообщения
12,970
Реакции
10,914
  • Команда форума
  • #11
А если углубиться в детали работы компилятора, то не 65, а 66, потому что виртуальной машине так удобнее данные раскладывать в памяти.
Для строк работает такое же правило, но там размер приводится так, чтобы он был кратен четырем.
 

Madness aka null138

Участник
Сообщения
713
Реакции
734
А если углубиться в детали работы компилятора, то не 65, а 66, потому что виртуальной машине так удобнее данные раскладывать в памяти.
Для строк работает такое же правило, но там размер приводится так, чтобы он был кратен четырем.
верно, забыл про это правило. я помню ты уже писал в одной теме.
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
Мой способ

Сначала, создадим что-то вроде структуры:
enum struct player
Только ты забыл уточнить, что это будет работать только начиная с версии SM1.11. И эта версия должна стоять на сервере, где будет юзаться плагин.
Сообщения автоматически склеены:

но людям удобнее вот так.
хотелось бы список этих людей поимённо (это много места не займёт ^_^).
 
  • Фэйспалм
Реакции: JDW

Rabb1t

Амбассадор
Сообщения
2,968
Реакции
1,429
  • Команда форума
  • #14
Только ты забыл уточнить, что это будет работать только начиная с версии SM1.11. И эта версия должна стоять на сервере, где будет юзаться плагин.
Сообщения автоматически склеены:

хотелось бы список этих людей поимённо (это много места не займёт ^_^).
1.10. Структуры в 1.10 ввели.
 
  • Мне нравится
Реакции: JDW

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
Можно всё это и так реализовать на предыдущих версиях 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 вывели.
 

Nico Yazawa

Бывший MrChester =(
Сообщения
326
Реакции
303
хотелось бы список этих людей поимённо (это много места не займёт ^_^).
Nico Yazawa и все любители Pawn на SA:MP

Можно всё это и так реализовать на предыдущих версиях SM:
Только потом тебе компилятор будет угрожать, мол в 1.11 такое чудо больше не поддерживается.
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
Только потом тебе компилятор будет угрожать, мол в 1.11 такое чудо больше не поддерживается.
старый синтаксис поддерживается, а новый - нет? О_о
Всё компилится на 11-й версии:
C-подобный:
//SourceMod Batch Compiler
// by the SourceMod Dev Team


//// 5.sp
//
// Code size:             3484 bytes
// Data size:             2280 bytes
// Stack/heap size:      16384 bytes
// Total requirements:   22148 bytes
//
// Compilation Time: 0,12 sec
// ----------------------------------------
Сообщения автоматически склеены:

все любители Pawn на SA:MP
Тю, что хотите в своём андреасе, то и делайте. Мне до этого дела нет.
 

Вложения

  • 5.smx
    2.4 КБ · Просмотры: 3
  • 5.sp
    478 байт · Просмотры: 8

Nico Yazawa

Бывший MrChester =(
Сообщения
326
Реакции
303
старый синтаксис поддерживается, а новый - нет? О_о
Всё компилится на 11-й версии:
Не знаю, я каждый раз когда пробовал делать двумерные массивы такие с enum, то выдавал варнинг. Загуглил решение и начал писать на таких структурах .-.
А на 1.11 я еще даже ничего не делал)
 

DarklSide

Участник
Сообщения
931
Реакции
468
[Статья] Способ хранения переменных для каждого игрока
Всем привет!
Решил заняться делом и поделиться своим опытом хранения переменных для каждого игрока.

Вступление
Для начала, хотел бы объяснить, что это и как вообще.
Иногда, в плагинах приходится хранить переменные, которые для каждого игрока будут свои.
Возьмем, к примеру, монеты. У каждого игрока это свое кол-во, значит надо создать 64 таких переменных. В каждой будет кол-во монет 1 клиента.

Можно сделать так, как целый массив:
C-подобный:
int coins[MAXPLAYER+1];

Тогда обращаться к ник мы будем так: (прибавим всем по 1 монетке):
C-подобный:
for(int i = 1; i <= MaxClients; i++)
{
    coins[i] += 1;
}
А представим, что таких переменных будет много, я думаю будет не очень удобно ими управлять.
И я хочу предложить вам мой способ.

Мой способ
Сначала, создадим что-то вроде структуры:
C-подобный:
enum struct player
{

}

Теперь, объявим данную структуру, как глобальную:
C-подобный:
player player_info[MAXPLAYERS + 1];
В данном случае player_info, это название нашей недоструктуры.

Отлично, давайте добавим в player несколько переменных. Это может быть любой тип: от int до Handle.
C-подобный:
enum struct player
{
    int coins;
    int money;
    int gold;
    // И так далее
}
Теперь у нас есть по 3 переменных, на каждого игрока.

Как же к ним обращаться?
Тут все просто, пишем наше название недоструктуры player_info, после в квадратных скобках пишем индекс игрока и через точку нашу переменную:
C-подобный:
PrintToChat(client, "Твои монетки: %i", player_info[client].coins);
PrintToChat(client, "Твои денюжки: %i", player_info[client].money);
PrintToChat(client, "Твоё золото: %i", player_info[client].gold);

Заключение
Этот способ не является чем-то обязательным в Вашем коде. Кто-то как хочет, так и прогает.
Я лишь предложил способ, которым всегда пользуюсь и которым мне правда удобнее всего.

Буду рад услышать Вашу критику или отзыв, если это Вам реально как-то помогло =)
Буду рад услышать Вашу критику или отзыв, если это Вам реально как-то помогло =)
Как то странно это прозвучало, что это "Ваш способ", особенно, если учесть что этот самый способ узнали относительно недавно. Это будет заводить в заблуждение новичков, т.к. вы не указали источник, другие возможности и ограничения в виде грамматики, либо словесно.
Предлагаю дополнить статью, в частности что описал выше, учитывая что enum struct это не только хранение переменных игроков, и концентрироваться на этом вовсе не стоит.
 
Последнее редактирование:

Nico Yazawa

Бывший MrChester =(
Сообщения
326
Реакции
303
Как то странно это прозвучало, что это "Ваш способ", особенно, если учесть что этот самый способ узнали относительно недавно. Это будет заводить в заблуждение новичков, т.к. вы не указали источник, другие возможности и ограничения в виде грамматики, либо словесно.
Да, способ точно не мой) подправлю. Дело в том, что этот способ был найден уже довольно давно, когда начали появляться варнинги об удалении этой возможности в 1.11 (как видим, нас обманули =( ). Я решил им поделиться, потому что он правда выглядит приятнее.

Предлагаю дополнить статью, в частности что описал выше, учитывая что enum struct это не только хранение переменных игроков, и концентрироваться на этом вовсе не стоит.
Да, спасибо за идею, дополню. Просто если бы удалили способ с двумерным массивом и enum, то это была бы единственная такая альтернатива.
 
Сверху Снизу