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

    Статус
    Оффлайн
    Регистрация
    22.10.2019
    Сообщений
    4
    Репутация:
    0 ±

    Как сделать систему стаков для инвентаря?

    Вообщем просто сломался мозг.

    Смотри
    Есть 20 ячеек слотов для предметов pInfo[playerid][pItem][20]
    Также 20 ячеек в которых хронится кол-во предмета из pInfo[playerid][pItem][20] - pInfo[playerid][pItemChar][20]
    Тоесть 1 ячейка pInfo[playerid][pItem][1] записывает кол-во в pInfo[playerid][pItemChar][1]
    Так вот, есть переменная которая хранит информацию о предмете
    Тут хранится число в которое должен стакатся предмет ItemsInfo[Ид предмета][Stack]
    Вопрос такой

    Как сделать что бы если мы дабовляем больше чем стакается предмет он раскидывался по ячейкам по стакам
    Вот код добавление предмета
    Код:
    stock AddItem(playerid, itemid, amount)
    {
        if(pInfo[playerid][pItem][0] != itemid && pInfo[playerid][pItem][1] != 0 && pInfo[playerid][pItem][2] != 0 && pInfo[playerid][pItem][3] != 0 && pInfo[playerid][pItem][4] != 0 && pInfo[playerid][pItem][5] != 0 && pInfo[playerid][pItem][6] != 0 && pInfo[playerid][pItem][7] != 0 && pInfo[playerid][pItem][8] != 0 && pInfo[playerid][pItem][9] != 0 && pInfo[playerid][pItem][10] != 0 && pInfo[playerid][pItem][11] != 0
        	 && pInfo[playerid][pItem][12] != itemid && pInfo[playerid][pItem][13] != 0 && pInfo[playerid][pItem][14] != 0 && pInfo[playerid][pItem][15] != 0 && pInfo[playerid][pItem][16] != 0 && pInfo[playerid][pItem][17] != 0 && pInfo[playerid][pItem][18] != 0 && pInfo[playerid][pItem][19] != 0) return SendClientMessage(playerid, 0xBE5555FF, "[Ошибка] {FFFFFF}У вас не хватает места в инвентаре!");
        for(new i = 0; i < 20; i++)
        {
            if(pInfo[playerid][pItem][i] != itemid) continue;
            if(pInfo[playerid][pItemChar][i] > ItemsInfo[itemid][Stack]) continue;
            pInfo[playerid][pItemChar][i] += amount;
            return 1;
        }
        for(new i = 0; i < 20; i++)
        {
     		if(amount < 1)  continue;
            if(pInfo[playerid][pItem][i] != 0) continue;
            if(amount > ItemsInfo[itemid][Stack])
            {	
            	pInfo[playerid][pItem][i] = itemid;
           		pInfo[playerid][pItemChar][i] = ItemsInfo[itemid][Stack];
            	amount -= ItemsInfo[itemid][Stack];
            	AddItem(playerid, itemid, amount);
            	continue;
            }
            pInfo[playerid][pItem][i] = itemid;
            pInfo[playerid][pItemChar][i] = amount;
            return 1;
        }
        return 1;
    }
    Пример:
    Придмет под идом 5 стакается по 3 шт
    Тоесть мы к примеру добавляем AddItem(playerid, 5, 6)
    и он записывает в 2 ячейки по 3 шт
    Последний раз редактировалось gw.h; 22.10.2019 в 17:28.

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

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    1) При добавлении предметов запускаешь цикл на перебор всех слотов.
    2) Если находишь предмет с тем же ID, проверяешь, заполнен ли слот по максимуму.
    2.1) Если в слоте есть место - добавляешь в него предметы. При этом, если добавляешь, например, 4 предмета, а места в слоте доступно всего для 2-х - добавляешь только два предмета и продолжаешь проверку других слотов.
    2.2) Если в слоте мест нет - пропускаешь его.
    3) В конце цикла смотришь, остались ли предметы на добавление. Если остались, начинаешь искать первый свободный слот и добавляешь остаток предметов в него.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

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

    Steve Pavlina

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

    Статус
    Оффлайн
    Регистрация
    22.10.2019
    Сообщений
    4
    Репутация:
    0 ±
    каким образом 3 пункт реализовать?
    вызвав цикл снова?

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

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

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

    Steve Pavlina

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

    Статус
    Оффлайн
    Регистрация
    22.10.2019
    Сообщений
    4
    Репутация:
    0 ±
    типо вызвать AddItem(playerid, itemid, amount) только уже с остатками
    получится цикл пока не закончится amount или слоты

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

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

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

    Steve Pavlina

  7. #7
    Аватар для gw.h
    Пользователь

    Статус
    Оффлайн
    Регистрация
    22.10.2019
    Сообщений
    4
    Репутация:
    0 ±
    Чувак можешь написать эту систему? а то у меня уже сил просто нет это сделать, у меня мозг стопорится на 2 пункте

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

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    1. stock AddItem(playerid, itemid, amount)
    2. {
    3. new temp;
    4. for(...)
    5. {
    6. if(id_предмета_в_слоте != itemid)
    7. continue;
    8. if(количество_предмета_в_слоте >= максимальное_количество_предмета_в_одном_слоте)
    9. continue;
    10.  
    11. temp = максимальное_количество_предмета_в_одном_слоте-количество_предмета_в_слоте;
    12. if(temp > amount)
    13. {
    14. количество_предмета_в_слоте = максимальное_количество_предмета_в_одном_слоте;
    15. amount -= temp;
    16. if(amount <= 0)
    17. return 1;
    18. }
    19. else
    20. {
    21. количество_предмета_в_слоте += amount;
    22. return 1;
    23. }
    24. }
    25. for(...)
    26. {
    27. if(id_предмета_в_слоте != свободный_слот)
    28. continue;
    29. id_предмета_в_слоте = itemid;
    30. количество_предмета_в_слоте = amount;
    31. break;
    32. }
    33. return 1;
    34. }


    Приблизительно, так. Дальше уж сам. Или в стол заказов пиши.

    UPD: Ну ниже скинули, собственно, доведённый до ума алгоритм, который я описал в этом сообщении.
    Последний раз редактировалось DeimoS; 22.10.2019 в 21:13.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

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

    Steve Pavlina

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

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Поделюсь своим понтокодом:
      Открыть/закрыть
    1. enum EItem // enum с кодами всех видов предметов
    2. {
    3. ITEM_NONE, // Для обозначения пустого места в слоте
    4. ITEM_DEAGLE,
    5.  
    6. // Объявим константу __MAX_ITEM так, чтобы она была равна
    7. // ID последнего объявленного ID предмета (т.е. ITEM_DEAGLE).
    8. // Это пригодится для проверки правильности кодов предметов.
    9. __DUMMY_ENUM_ITEM,
    10. __MAX_ITEM = __DUMMY_ENUM_ITEM - 2
    11. };
    12.  
    13. #define MAX_ITEM_SLOTS 15 // Допустим, игрок может таскать до 15 разных предметов.
    14. #define MAX_ITEM_AMOUNT 10 // До 10 предметов на слот (при желании можно сделать массив
    15. // и в нём отдельно установить максимум для каждого предмета).
    16.  
    17. enum EPlayerInfo
    18. {
    19. pAccID,
    20. pLevel,
    21. pMoney,
    22. // ...
    23. EItem:pItems[MAX_ITEM_SLOTS], // Слоты для предметов
    24. pNumItems[MAX_ITEM_SLOTS] // Кол-во предмета в каждом слоте
    25. };
    26. new player_info[MAX_PLAYERS][EPlayerInfo];
    27.  
    28. Inventory_AddItem(playerid, EItem:item, amount)
    29. {
    30. // Для отлова ошибок с помощью crashdetect
    31. assert(item > ITEM_NONE);
    32. assert(item <= __MAX_ITEM);
    33. assert(amount > 0);
    34.  
    35. // 1-й цикл: проверяем, есть ли такой предмет в инвентаре
    36. for (new i = 0; i < MAX_ITEM_SLOTS; ++i)
    37. {
    38. // Если уже есть - переходим к накоплению в одном слоте
    39. if (player_info[playerid][pItems][i] == item)
    40. {
    41. // Если добавляемое количество не выходит за лимит слота
    42. // просто сохраним всё в в этом слоте и выйдем из функции.
    43. // "return 0" означает, что мы сохранили всё без остатка.
    44. if (player_info[playerid][pNumItems][i] + amount <= MAX_ITEM_SLOTS)
    45. {
    46. player_info[playerid][pNumItems][i] += amount;
    47. return 0;
    48. }
    49. // Если же количество слишком большое для одного слота,
    50. // добавляем в слот лишь столько, сколько вместится,
    51. // оставшееся потом попытаемся добавить в другой слот.
    52. amount -= (MAX_ITEM_SLOTS - player_info[playerid][pNumItems][i]);
    53. player_info[playerid][pNumItems][i] = MAX_ITEM_SLOTS;
    54. }
    55. }
    56.  
    57. // 2-й цикл: пробуем добавить в пустые слоты.
    58. for (new i = 0; i < MAX_ITEM_SLOTS; ++i)
    59. {
    60. if (player_info[playerid][pItems][i] == ITEM_NONE)
    61. {
    62. player_info[playerid][pItems][i] = item;
    63. if (amount <= MAX_ITEM_SLOTS)
    64. {
    65. player_info[playerid][pNumItems][i] = amount;
    66. return 0;
    67. }
    68. amount -= MAX_ITEM_SLOTS;
    69. player_info[playerid][pNumItems][i] = MAX_ITEM_SLOTS;
    70. }
    71. }
    72.  
    73. // Если не нашлось достаточно слотов, чтобы сохранить предмет,
    74. // вернём оставшееся количество, для которого не нашлось места.
    75. // Так если мы попытаемся сохранить предмет в большем количестве,
    76. // чем может вместить инвентарь, то сможем узнать, сколько не вместилось.
    77. return amount;
    78. }

    Предупреждаю сразу, работоспособность не проверял.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  10. Пользователь сказал cпасибо:
    whale (23.10.2019)
 

 

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

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

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

Ваши права

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