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

    Статус
    Оффлайн
    Регистрация
    09.03.2018
    Сообщений
    255
    Репутация:
    24 ±

    Взаимодействие с активным списком массива.

    Здравствуйте.

    Существует массив, который может изменять значения прямо тогда, когда его перебирает какой-то игрок. То есть, игрок нажмёт клавишу вперёд - ему покажет последующие 5 валидных значений, нажмёт назад - покажет предыдущие.
    Например:

    1. new
    2. array_list[100] = {5, 6, 7, ...};


    Показали игроку первые пять значений списка (array_list[0], array_list[1], ...)
    Затем изменили значение для 6-й ячейки на невалидное (-1) и следующие пять будут браться не array_list[5], а array_list[6], array_list[7] ...
    Так-же может сложиться ситуации, что показали значения 0-4 ячейки массива и в это время данные в какой-то из этих значений может измениться и как это учесть - без понятия.

    С перебором неизменяемых и последовательных значений есть опыт, а в таких, нет.
    Если есть хоть какие-либо предположения/мысля - рад буду выслушать все)

  2. #2
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Я бы сказал, что если у тебя допускается возможность изменять данные, с которыми в данный момент работают и, при этом, актуальность данных важна, то, вероятнее всего, в реализованной тобой логике системы что-то не так.

    Ну а вообще единственный вариант, который я вижу - при изменении данных проверять, показываются ли они кому-то и если показываются - сообщать об изменения и/или по новой показывать данные, но уже пропуская изменённые (если они стали невалидными). Либо если игрок пытается взаимодействовать с уже изменёнными данными - сообщать ему об ошибке и показывать уже актуальные данные.

    Вообще было бы лучше, если бы ты более конкретизировал пример, рассказав что ты пытаешься сделать, что вообще за данные и почему/когда они могут изменяться (а так же почему важно, чтоб у просматривающего данные игрока, список показанных данных всегда был актуальным).
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  3. #3
    Аватар для execution
    Пользователь

    Статус
    Оффлайн
    Регистрация
    09.03.2018
    Сообщений
    255
    Репутация:
    24 ±
    Цитата Сообщение от DeimoS Посмотреть сообщение
    Я бы сказал, что если у тебя допускается возможность изменять данные, с которыми в данный момент работают и, при этом, актуальность данных важна, то, вероятнее всего, в реализованной тобой логике системы что-то не так.

    Ну а вообще единственный вариант, который я вижу - при изменении данных проверять, показываются ли они кому-то и если показываются - сообщать об изменения и/или по новой показывать данные, но уже пропуская изменённые (если они стали невалидными). Либо если игрок пытается взаимодействовать с уже изменёнными данными - сообщать ему об ошибке и показывать уже актуальные данные.

    Вообще было бы лучше, если бы ты более конкретизировал пример, рассказав что ты пытаешься сделать, что вообще за данные и почему/когда они могут изменяться (а так же почему важно, чтоб у просматривающего данные игрока, список показанных данных всегда был актуальным).
    Система управлением автосалонов.
    Есть возможность добавлять/удалять автомобили прямо из игры. Показ автомобилей на выбор не больше, чем 5 шт за раз

  4. #4
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Цитата Сообщение от execution Посмотреть сообщение
    Система управлением автосалонов.
    Есть возможность добавлять/удалять автомобили прямо из игры. Показ автомобилей на выбор не больше, чем 5 шт за раз
    А кто их может добавлять/удалять? И насколько часто это может быть?

    Пока что не вижу ни одной причины, которая мешала бы сделать так, что даже если, во время открытия списка авто, удалили то авто, которое игрок выбрал, то игрок всё равно мог бы его купить. Либо наоборот не мог и видел сообщение, а-ля: "Данный автомобиль более недоступен".
    Тут отталкиваться нужно исключительно от того, чего ты хочешь добиться и для чего.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  5. #5
    Аватар для execution
    Пользователь

    Статус
    Оффлайн
    Регистрация
    09.03.2018
    Сообщений
    255
    Репутация:
    24 ±
    Цитата Сообщение от DeimoS Посмотреть сообщение
    А кто их может добавлять/удалять? И насколько часто это может быть?

    Пока что не вижу ни одной причины, которая мешала бы сделать так, что даже если, во время открытия списка авто, удалили то авто, которое игрок выбрал, то игрок всё равно мог бы его купить. Либо наоборот не мог и видел сообщение, а-ля: "Данный автомобиль более недоступен".
    Тут отталкиваться нужно исключительно от того, чего ты хочешь добиться и для чего.
    Управлять могут администраторы, возможно в будущем будут изменения.
    На счёт проверки наличия во время покупки - согласен, спасибо

    А что на счёт перебора авто группами?
    Допустим я буду сохранять индексы пяти показываемых авто, соответственно буду сохранять и номер страницы. Удалили в автосалоне 3 автомобиля, и я нажимаю далее -> по формуле номер_страницы*кол-во_показа_за_раз я получу якобы последний индекс, но уже это будет не последний и как в этом случае быть?

  6. #6
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Тебе нужно решить, настолько ли важно не давать игроку покупать автомобиль, который удалил администратор.

    Если не так важно - при первом открытии списка автомобилей выгружай не 5 автомобилей, а сразу все и сохраняй пришедший кэш. Далее уже работай с этим кэшем и тогда тебе будет совершенно всё равно на то, что происходит с самой таблицей. Собственно, это, как по мне, самый правильный вариант, ибо ситуация, при которой администратор удаляет автомобиль прямо во время игры - это не очень нормально. Лучше уж тогда просто помечать их для удаления, выделив под это столбец, и при следующем запуске мода уже непосредственно удалить их, не мешая , тем самым, игровому процессу.

    Но даже если важно - всё равно нужно грузить все автомобили и работать с кэшем, а не мучить БД постоянными запросами. Собственно, по переменной, которая будет хранить кэш, можно будет определять то, какому игроку показывается список, и, при удалении одного из авто, по новой загружать данные для всех игроков с открытыми списками, сообщая в чате, что в таблице были совершены изменения.


    Вот, если что, пример того, как можно работать с кэшем в подобном случае:
      Открыть/закрыть
    1. new pVar__BanLog_Cache[] = "pVar__BanLog_Cache";
    2. new pVar__BanLog_Page[] = "pVar__BanLog_Page";
    3. new pVar__BanLog_BannedName[] = "pVar__BanLog_BannedName";
    4.  
    5. const MAX_ROW_IN_BANLOG_DIALOG_PAGE = 30;
    6. const dBanLogList = 666;


    1. CMD:checkban(playerid, params[])
    2. {
    3. if(pl[playerid][pAdmin]<4)return 1;
    4. if(isnull(params)) return send(playerid, COLOR_GRAD1, "/checkban Nick_Name");
    5.  
    6. ShowPlayerBanLogForPlayer(playerid, params);
    7. return 1;
    8. }


    1. stock ShowPlayerBanLogForPlayer(playerid, const banned_player_name[])
    2. {
    3. if(GetPVarType(playerid, pVar__BanLog_Cache))
    4. {
    5. new Cache:cache_id = Cache:GetPVarInt(playerid, pVar__BanLog_Cache);
    6.  
    7. if(cache_is_valid(cache_id))
    8. cache_delete(cache_id);
    9.  
    10. DeletePVar(playerid, pVar__BanLog_Cache);
    11. DeletePVar(playerid, pVar__BanLog_Page);
    12. DeletePVar(playerid, pVar__BanLog_BannedName);
    13. }
    14.  
    15. new query_string[78+MAX_PLAYER_NAME+1];
    16. mysql_format(mysql_connect_ID, query_string, sizeof(query_string),
    17. "SELECT Nick, BanDate, AdmNick, Reason FROM banhistory WHERE Nick='%e' ORDER BY BanDate", banned_player_name);
    18. mysql_tquery(mysql_connect_ID, query_string, "@MySQL__PlayerBanLog", "i", playerid);
    19. SetPVarString(playerid, pVar__BanLog_BannedName, banned_player_name);
    20. }



    1. @MySQL__PlayerBanLog(playerid);
    2. @MySQL__PlayerBanLog(playerid)
    3. {
    4. new rows;
    5. cache_get_row_count(rows);
    6. if(!rows)
    7. {
    8. SendClientMessage(playerid, 0xFFFFFFFF, "Ошибка: Указанный игрок не найден или не был забанен.");
    9. return;
    10. }
    11.  
    12. if(rows > MAX_ROW_IN_BANLOG_DIALOG_PAGE)
    13. {
    14. SetPVarInt(playerid, pVar__BanLog_Cache, _:cache_save());
    15. }
    16.  
    17. ShowPlayerBanLogCache(playerid);
    18. }


    1. stock ShowPlayerBanLogCache(playerid)
    2. {
    3. if(!GetPVarType(playerid, pVar__BanLog_Cache))
    4. {
    5. SendClientMessage(playerid, 0xFFFFFFFF,
    6. "При отображении списка блокировок произошла ошибка [#001]. Повторите попытку.");
    7. return;
    8. }
    9.  
    10. new Cache:cache_id = Cache:GetPVarInt(playerid, pVar__BanLog_Cache);
    11.  
    12. if(!cache_is_valid(cache_id))
    13. {
    14. DeletePVar(playerid, pVar__BanLog_Cache);
    15. DeletePVar(playerid, pVar__BanLog_Page);
    16. DeletePVar(playerid, pVar__BanLog_BannedName);
    17. SendClientMessage(playerid, 0xFFFFFFFF,
    18. "При отображении списка блокировок произошла ошибка [#002]. Повторите попытку.");
    19. return;
    20. }
    21.  
    22. if(cache_is_any_active())
    23. cache_unset_active();
    24.  
    25. cache_set_active(cache_id);
    26.  
    27. new rows;
    28. cache_get_row_count(rows);
    29.  
    30. new page = GetPVarInt(playerid, pVar__BanLog_Page);
    31.  
    32. new i = page*MAX_ROW_IN_BANLOG_DIALOG_PAGE;
    33. new max_i = i + MAX_ROW_IN_BANLOG_DIALOG_PAGE;
    34. if(max_i > rows)
    35. max_i = rows;
    36.  
    37. new ban_date[22];
    38. new admin_name[MAX_PLAYER_NAME - 3];
    39. new reason[20];
    40.  
    41. new dialog_string[(2+5+sizeof(ban_date)+sizeof(admin_name)+sizeof(reason))*MAX_ROW_IN_BANLOG_DIALOG_PAGE+1];
    42. dialog_string = "№. Админ.\tДата блокировки\tПричина\n";
    43.  
    44. for(; i < max_i; i++)
    45. {
    46. cache_get_value_name(i, "BanDate", ban_date);
    47. cache_get_value_name(i, "AdmNick", admin_name);
    48. cache_get_value_name(i, "Reason", reason);
    49.  
    50. format(dialog_string, sizeof(dialog_string), "%s%i. %s\t%s\t%s\n", dialog_string, i + 1, admin_name, ban_date, reason);
    51. }
    52.  
    53. if(rows > MAX_ROW_IN_BANLOG_DIALOG_PAGE)
    54. {
    55. if(max_i < rows)
    56. {
    57. strcat(dialog_string, "»» Далее\n");
    58. }
    59. if(page > 0)
    60. {
    61. strcat(dialog_string, "«« Назад\n");
    62. }
    63. }
    64.  
    65. new banned_player_name[MAX_PLAYER_NAME];
    66. GetPVarString(playerid, pVar__BanLog_BannedName, banned_player_name, MAX_PLAYER_NAME);
    67. ShowPlayerDialog(playerid, dBanLogList, DIALOG_STYLE_TABLIST_HEADERS, banned_player_name, dialog_string, "Выбрать", "Закрыть");
    68. }



    1. public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
    2. {
    3. switch(dialogid)
    4. {
    5. case dBanLogList:
    6. {
    7. if(!GetPVarType(playerid, pVar__BanLog_Cache))
    8. {
    9. SendClientMessage(playerid, 0xFFFFFFFF,
    10. "При отображении списка использований промокода произошла ошибка [#003]. Повторите попытку.");
    11. return 1;
    12. }
    13. new Cache:cache_id = Cache:GetPVarInt(playerid, pVar__BanLog_Cache);
    14.  
    15. if(!cache_is_valid(cache_id))
    16. {
    17. DeletePVar(playerid, pVar__BanLog_Cache);
    18. DeletePVar(playerid, pVar__BanLog_Page);
    19. DeletePVar(playerid, pVar__BanLog_BannedName);
    20. SendClientMessage(playerid, 0xFFFFFFFF,
    21. "При отображении списка использований промокода произошла ошибка [#004]. Повторите попытку.");
    22. return 1;
    23. }
    24.  
    25. if(!response)
    26. {
    27. cache_delete(cache_id);
    28. DeletePVar(playerid, pVar__BanLog_Cache);
    29. DeletePVar(playerid, pVar__BanLog_Page);
    30. DeletePVar(playerid, pVar__BanLog_BannedName);
    31. return 1;
    32. }
    33.  
    34. if(!strcmp(inputtext, "»» Далее"))
    35. {
    36. SetPVarInt(playerid, pVar__BanLog_Page, GetPVarInt(playerid, pVar__BanLog_Page)+1);
    37. ShowPlayerBanLogCache(playerid);
    38. }
    39. else if(!strcmp(inputtext, "«« Назад"))
    40. {
    41. SetPVarInt(playerid, pVar__BanLog_Page, GetPVarInt(playerid, pVar__BanLog_Page)-1);
    42. if(GetPVarInt(playerid, pVar__BanLog_Page) < 1)
    43. DeletePVar(playerid, pVar__BanLog_Page);
    44. ShowPlayerBanLogCache(playerid);
    45. }
    46. else
    47. {
    48. ShowPlayerBanLogCache(playerid);
    49. }
    50. return 1;
    51. }
    52. }
    53. return 1;
    54. }



    1. public OnPlayerDisconnect(playerid, reason)
    2. {
    3. if(GetPVarType(playerid, pVar__BanLog_Cache))
    4. {
    5. new Cache:cache_id = Cache:GetPVarInt(playerid, pVar__BanLog_Cache);
    6.  
    7. if(cache_is_valid(cache_id))
    8. cache_delete(cache_id);
    9. }
    10. return 1;
    11. }
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  7. Пользователь сказал cпасибо:
    execution (29.09.2020)
 

 

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

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

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

Ваши права

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