Zzerss

Base para un sistema de inventario

Sep 9th, 2023 (edited)
576
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 11.78 KB | Gaming | 0 0
  1. #define MAX_INVENTORY_SLOTS 28 //Slots maximos
  2. #define MAX_ITEM_TYPES 5 //Items maximos de la array "ItemInfo"
  3.  
  4. enum
  5. {
  6.     e_ITEM_COFRE_HIERRO,
  7.     e_ITEM_COFRE_BRONCE,
  8.     e_ITEM_COFRE_PLATA,
  9.     e_ITEM_COFRE_ORO,
  10.     e_ITEM_COFRE_CRYSTAL
  11. }
  12. enum e_ITEMS
  13. {
  14.     e_Item_TYPE,
  15.     bool:e_Item_SLOT_USED,
  16.     e_ITEM_SLOT,
  17.     e_ITEM_SLOT_CANTIDAD_ALMACENADA
  18. };
  19.  
  20. new Inventory[MAX_PLAYERS][ e_ITEMS ][ MAX_INVENTORY_SLOTS ];
  21. new ItemCount[MAX_PLAYERS][MAX_ITEM_TYPES];
  22.  
  23. enum enum_ItemInfo
  24. {
  25.     ID_ITEM_Inventory,
  26.     Item_MaxSave_Slot,
  27.     Item_Name[24]
  28. }
  29. new ItemInfo[MAX_ITEM_TYPES][ enum_ItemInfo ] = //Aca se añaden los objetos o items, el id, la cantidad maxima para guardar en cada slot, y el nombre
  30. {
  31.     {e_ITEM_COFRE_HIERRO, 10, "HIERRO"},
  32.     {e_ITEM_COFRE_BRONCE, 5, "BRONCE"},
  33.     {e_ITEM_COFRE_PLATA, 100, "PLATA"},
  34.     {e_ITEM_COFRE_ORO, 1, "ORO"},
  35.     {e_ITEM_COFRE_CRYSTAL, 1, "CRYSTAL"}
  36. };
  37.  
  38.  
  39. CMD:inventarioprueba(playerid, params[]) //Agregar ID del item y la cantidad
  40. {
  41.     new iddd,iddd1;
  42.     if(sscanf(params, "dd",iddd,iddd1)) return SendClientMessage(playerid, -1,"Agregar ID del item y la cantidad");
  43.     AddItemToInventory(playerid, iddd,iddd1);
  44.     return 1;
  45. }
  46. CMD:borrarinventario(playerid, params[]) //Borrar id del item y la cantidad
  47. {
  48.     new iddd,iddd1;
  49.     if(sscanf(params, "dd",iddd,iddd1)) return SendClientMessage(playerid, -1,"Borrar id del item y la cantidad");
  50.     RemoveItemFromInventory(playerid, iddd, iddd1);
  51.     return 1;
  52. }
  53. CMD:buscaritem(playerid, params[]) //Buscar la cantidad especifica de un item mediante la id
  54. {
  55.     new itemid;
  56.     if(sscanf(params, "d",itemid)) return 1;
  57.     CountItemInInventory(playerid, itemid);
  58.     return 1;
  59. }
  60. CMD:inventarioxd(playerid, params[]) //Mostrar los items del inventario. Slot y cantidad.
  61. {
  62.     new string[128];
  63.     format(string, sizeof(string), "Inventario de %s:", GetName(playerid));
  64.     SendClientMessage(playerid, -1, string);
  65.  
  66.     for(new i = 0; i < MAX_INVENTORY_SLOTS; i++)
  67.     {
  68.         if(Inventory[playerid][e_Item_SLOT_USED][i])
  69.         {
  70.             new itemid = Inventory[playerid][e_Item_TYPE][i];
  71.             new name[24];
  72.             strmid(name, ItemInfo[itemid][Item_Name], 0, sizeof(name));
  73.             new amount = Inventory[playerid][e_ITEM_SLOT_CANTIDAD_ALMACENADA][i];
  74.             format(string, sizeof(string), "Slot %d: %s x%d", i + 1, name, amount);
  75.             SendClientMessage(playerid, -1, string);
  76.         }
  77.     }
  78.     return 1;
  79. }
  80.  
  81.  
  82. stock AddItemToInventory(playerid, itemid, amount)
  83. {
  84.     if(CanAddItemToInventory(playerid, itemid, amount) == 0) return SendClientMessage(playerid, -1,"** No se puede llenar el inventario con esa cantidad de objetos, intentalo de nuevo.");
  85.     if(CountAvailableSlots(playerid) == 0) return SendClientMessage(playerid, -1,"** No hay slots disponibles.");
  86.     new maxPerSlot = ItemInfo[itemid][Item_MaxSave_Slot];
  87.  
  88.     //intentamos llenar los slots existentes que ya contienen el mismo tipo de ítem
  89.     for(new i = 0; i < MAX_INVENTORY_SLOTS; i++)
  90.     {
  91.         if(Inventory[playerid][e_Item_SLOT_USED][i] && Inventory[playerid][e_Item_TYPE][i] == itemid)
  92.         {
  93.             new spaceLeft = maxPerSlot - Inventory[playerid][e_ITEM_SLOT_CANTIDAD_ALMACENADA][i];
  94.             new toAdd = min(amount, spaceLeft);
  95.             Inventory[playerid][e_ITEM_SLOT_CANTIDAD_ALMACENADA][i] += toAdd;
  96.             amount -= toAdd;
  97.             if(amount <= 0)
  98.             {
  99.                 break;
  100.             }
  101.         }
  102.     }
  103.  
  104.     // Si aún quedan ítems por agregar, creamos nuevos slots
  105.     if(amount > 0)
  106.     {
  107.         for(new i = 0; i < MAX_INVENTORY_SLOTS; i++)
  108.         {
  109.             if(!Inventory[playerid][e_Item_SLOT_USED][i])
  110.             {
  111.                 Inventory[playerid][e_Item_TYPE][i] = itemid;
  112.                 Inventory[playerid][e_Item_SLOT_USED][i] = true;
  113.                 Inventory[playerid][e_ITEM_SLOT_CANTIDAD_ALMACENADA][i] = min(amount, maxPerSlot);
  114.                 amount -= Inventory[playerid][e_ITEM_SLOT_CANTIDAD_ALMACENADA][i];
  115.                 if(amount <= 0)
  116.                 {
  117.                     break;
  118.                 }
  119.             }
  120.         }
  121.     }
  122.  
  123.     if(amount > 0)
  124.     {
  125.         printf("No hay suficientes slots de inventario para almacenar el ítem.");
  126.         return 0;
  127.     }
  128.  
  129.     ItemCount[playerid][itemid] += amount;
  130.  
  131.     //reorganizamos el inventario para asegurarnos de que todos los slots estén ordenados correctamente
  132.     OrganizeInventory(playerid);
  133.  
  134.     return 1;
  135. }
  136. /*
  137. stock RemoveItemFromInventory(playerid, itemid, amount)
  138. {
  139.     // Primero, verificamos si el jugador tiene suficientes ítems para remover
  140.     if(ItemCount[playerid][itemid] < amount)
  141.     {
  142.         SendClientMessage(playerid, -1, "No tienes suficientes ítems para remover esa cantidad.");
  143.         return 0;
  144.     }
  145.  
  146.     // Luego, removemos los ítems de los slots del inventario
  147.     for(new i = 0; i < MAX_INVENTORY_SLOTS; i++)
  148.     {
  149.         if(Inventory[playerid][e_Item_SLOT_USED][i] && Inventory[playerid][e_Item_TYPE][i] == itemid)
  150.         {
  151.             new toRemove = min(amount, Inventory[playerid][e_ITEM_SLOT_CANTIDAD_ALMACENADA][i]);
  152.             Inventory[playerid][e_ITEM_SLOT_CANTIDAD_ALMACENADA][i] -= toRemove;
  153.             amount -= toRemove;
  154.             if(Inventory[playerid][e_ITEM_SLOT_CANTIDAD_ALMACENADA][i] == 0)
  155.             {
  156.                 Inventory[playerid][e_Item_SLOT_USED][i] = false;
  157.                 Inventory[playerid][e_Item_TYPE][i] = -1;
  158.             }
  159.             if(amount <= 0)
  160.             {
  161.                 break;
  162.             }
  163.         }
  164.     }
  165.  
  166.     // Actualizamos el recuento total de ítems del jugador
  167.     ItemCount[playerid][itemid] -= amount;
  168.  
  169.     // Finalmente, reorganizamos el inventario para asegurarnos de que todos los slots estén ordenados correctamente
  170.     OrganizeInventory(playerid);
  171.  
  172.     return 1;
  173. }
  174. */
  175. stock RemoveItemFromInventory(playerid, itemid, amount)
  176. {
  177.     //verificamos si el jugador tiene suficientes ítems para remover
  178.     if(ItemCount[playerid][itemid] < amount)
  179.     {
  180.         SendClientMessage(playerid, -1, "No tienes suficientes ítems para remover esa cantidad.");
  181.         return 0;
  182.     }
  183.  
  184.     //removemos los ítems de los slots del inventario, empezando por los slots con menor cantidad
  185.     new minSlot = -1;
  186.     new minAmount = 999999;
  187.     while(amount > 0)
  188.     {
  189.         minSlot = -1;
  190.         minAmount = 999999;
  191.         for(new i = 0; i < MAX_INVENTORY_SLOTS; i++)
  192.         {
  193.             if(Inventory[playerid][e_Item_SLOT_USED][i] && Inventory[playerid][e_Item_TYPE][i] == itemid && Inventory[playerid][e_ITEM_SLOT_CANTIDAD_ALMACENADA][i] < minAmount)
  194.             {
  195.                 minSlot = i;
  196.                 minAmount = Inventory[playerid][e_ITEM_SLOT_CANTIDAD_ALMACENADA][i];
  197.             }
  198.         }
  199.         if(minSlot == -1)
  200.             break;
  201.         new toRemove = min(amount, Inventory[playerid][e_ITEM_SLOT_CANTIDAD_ALMACENADA][minSlot]);
  202.         Inventory[playerid][e_ITEM_SLOT_CANTIDAD_ALMACENADA][minSlot] -= toRemove;
  203.         amount -= toRemove;
  204.         if(Inventory[playerid][e_ITEM_SLOT_CANTIDAD_ALMACENADA][minSlot] == 0)
  205.         {
  206.             Inventory[playerid][e_Item_SLOT_USED][minSlot] = false;
  207.             Inventory[playerid][e_Item_TYPE][minSlot] = -1;
  208.         }
  209.     }
  210.  
  211.     // Actualizamos el recuento total de ítems del jugador
  212.     ItemCount[playerid][itemid] -= amount;
  213.  
  214.     //reorganizamos el inventario para asegurarnos de que todos los slots estén ordenados correctamente
  215.     OrganizeInventory(playerid);
  216.  
  217.     return 1;
  218. }
  219.  
  220.  
  221. stock CountAvailableSlots(playerid)
  222. {
  223.     new countxd = 0;
  224.     for(new i = 0; i < MAX_INVENTORY_SLOTS; i++)
  225.     {
  226.         if(!Inventory[playerid][e_Item_SLOT_USED][i])
  227.         {
  228.             countxd++;
  229.         }
  230.     }
  231.     return countxd;
  232. }
  233.  
  234. stock CanAddItemToInventory(playerid, itemid, amount)
  235. {
  236.     new maxPerSlot = ItemInfo[itemid][Item_MaxSave_Slot];
  237.  
  238.     //intentamos llenar los slots existentes que ya contienen el mismo tipo de ítem
  239.     for(new i = 0; i < MAX_INVENTORY_SLOTS; i++)
  240.     {
  241.         if(Inventory[playerid][e_Item_SLOT_USED][i] && Inventory[playerid][e_Item_TYPE][i] == itemid)
  242.         {
  243.             new spaceLeft = maxPerSlot - Inventory[playerid][e_ITEM_SLOT_CANTIDAD_ALMACENADA][i];
  244.             amount -= min(amount, spaceLeft);
  245.             if(amount <= 0)
  246.             {
  247.                 return 1;
  248.             }
  249.         }
  250.     }
  251.  
  252.     //si aún quedan ítems por agregar, verificamos si hay suficientes slots vacíos
  253.     for(new i = 0; i < MAX_INVENTORY_SLOTS; i++)
  254.     {
  255.         if(!Inventory[playerid][e_Item_SLOT_USED][i])
  256.         {
  257.             amount -= min(amount, maxPerSlot);
  258.             if(amount <= 0)
  259.             {
  260.                 return 1;
  261.             }
  262.         }
  263.     }
  264.  
  265.     //Si aún quedan ítems por agregar, significa que no hay suficiente espacio en el inventario
  266.     if(amount > 0)
  267.     {
  268.         return 0;
  269.     }
  270.  
  271.     return 1;
  272. }
  273.  
  274. stock OrganizeInventory(playerid)
  275. {
  276.     new tempInventory[MAX_INVENTORY_SLOTS][3];
  277.     new count = 0;
  278.  
  279.     // Copiamos todos los slots usados a una matriz temporal
  280.     for(new i = 0; i < MAX_INVENTORY_SLOTS; i++)
  281.     {
  282.         if(Inventory[playerid][e_Item_SLOT_USED][i])
  283.         {
  284.             tempInventory[count][0] = Inventory[playerid][e_Item_TYPE][i];
  285.             tempInventory[count][1] = Inventory[playerid][e_ITEM_SLOT_CANTIDAD_ALMACENADA][i];
  286.             tempInventory[count++][2] = ItemInfo[Inventory[playerid][e_Item_TYPE][i]][Item_MaxSave_Slot];
  287.         }
  288.     }
  289.  
  290.     // Ordenamos la matriz temporal por tipo de ítem y cantidad almacenada
  291.     for(new i = 0; i < count - 1; i++)
  292.     {
  293.         for(new j = i + 1; j < count; j++)
  294.         {
  295.             if(tempInventory[i][0] > tempInventory[j][0] || (tempInventory[i][0] == tempInventory[j][0] && tempInventory[i][1] < tempInventory[j][1]))
  296.             {
  297.                 SwapArray(tempInventory[i], tempInventory[j], 3);
  298.             }
  299.         }
  300.     }
  301.  
  302.     // Copiamos la matriz temporal ordenada de vuelta al inventario del jugador
  303.     for(new i = 0; i < MAX_INVENTORY_SLOTS; i++)
  304.     {
  305.         if(i < count)
  306.         {
  307.             Inventory[playerid][e_Item_TYPE][i] = tempInventory[i][0];
  308.             Inventory[playerid][e_Item_SLOT_USED][i] = true;
  309.             Inventory[playerid][e_ITEM_SLOT_CANTIDAD_ALMACENADA][i] = tempInventory[i][1];
  310.             ItemCount[playerid][i] = tempInventory[i][1];
  311.  
  312.         }
  313.     }
  314.  
  315.     return 1;
  316. }
  317.  
  318.  
  319. stock CountItemInInventory(playerid, itemid)
  320. {
  321.     if(!HasItem(playerid, itemid)) return SendClientMessage(playerid,-1,"No hay de esos items en el inventario");
  322.     new total = 0;
  323.     new string[128];
  324.     format(string, sizeof(string), "Inventario de %s:", GetName(playerid));
  325.     SendClientMessage(playerid, -1, string);
  326.  
  327.     for(new i = 0; i < MAX_INVENTORY_SLOTS; i++)
  328.     {
  329.         if(Inventory[playerid][e_Item_SLOT_USED][i] && Inventory[playerid][e_Item_TYPE][i] == itemid)
  330.         {
  331.             new amount = Inventory[playerid][e_ITEM_SLOT_CANTIDAD_ALMACENADA][i];
  332.             total += amount;
  333.             format(string, sizeof(string), "Slot %d: %d", i + 1, amount);
  334.             SendClientMessage(playerid, -1, string);
  335.         }
  336.     }
  337.  
  338.     format(string, sizeof(string), "Total: %d", total);
  339.     SendClientMessage(playerid, -1, string);
  340.  
  341.     return total;
  342. }
  343.  
  344.  
  345. stock HasItem(playerid, itemid)
  346. {
  347.     for(new i = 0; i < MAX_INVENTORY_SLOTS; i++)
  348.     {
  349.         if(Inventory[playerid][e_Item_SLOT_USED][i] && Inventory[playerid][e_Item_TYPE][i] == itemid)
  350.         {
  351.             return 1;
  352.         }
  353.     }
  354.     return 0;
  355. }
  356.  
  357.  
  358. stock SwapArray(arr1[], arr2[], size)
  359. {
  360.     new temp;
  361.     for(new i = 0; i < size; i++)
  362.     {
  363.         temp = arr1[i];
  364.         arr1[i] = arr2[i];
  365.         arr2[i] = temp;
  366.     }
  367. }
  368.  
Add Comment
Please, Sign In to add comment