- Home /
Stacking Items in a Inventory List
I have my inventory script, an enemy script with item dropping and looting, and an Item Class script all in Java. It all works fine, but I'm trying to find a way to make Items stackable. I have added a stackable boolean to my items and set them to true as well as a stack limit and amount variable. What I don't understand is how, when a button is clicked, can I search through a list for that item, if it exists change a varialble on that item. That is my only problem with this script right now. Here are those scripts(one being just a snippet).
My Item Class.
class ItemClass{
public var ItemID : int;
public var Name : String;
public var icon : Texture2D;
public var Description : String;
public var Value : int;
var Amount : int;
public var itemType : ItemType;
public var potionType : PotionType;
public var potionAmount : int;
public var stackAble : boolean;
public var maxStack : int;
public enum ItemType{
Potion,
Weapon,
QuestItem
};
public enum PotionType{
None,
Heal,
Stamplus,
strplus,
agplus
};
}
My Enemy
import System.Collections.Generic;
var life = 100;
var exp = 50;
var drops : List.<ItemClass> = new List.<ItemClass>();
var looting : boolean = false;
var lootable : boolean = false;
var lootRect : Rect = Rect(500,500,250,75);
var LOOT_ID : int = 3;
var skin : GUISkin;
function Start () {
}
function Update () {
if (life <= 0 && lootable == false ){
gameObject.SendMessageUpwards("AddExp", exp);
gameObject.tag = "Lootable";
lootable = true;
}
}
function OnGUI(){
GUI.skin = skin;
var levelManager = GameObject.Find("LevelManager").GetComponent(LevelManager);
if(looting == true && levelManager.paused == true ){
lootRect = GUI.Window(LOOT_ID,lootRect,LootWindow,"Looting" + this.name);
lootRect.y = Mathf.Clamp(lootRect.y,0,Screen.height-lootRect.height);
lootRect.x = Mathf.Clamp(lootRect.x,0,Screen.width-lootRect.width);
}
if(looting == true && levelManager.paused == false){
looting = false;
}
}
function Hit(){
life -= 10;
}
function LootWindow(id : int){
GUI.BringWindowToFront(id);
GUI.DragWindow(Rect(20,0,lootRect.width-20 ,15));
for( var x : int = 0; x< drops.Count; x++){
if(GUI.Button(Rect(10 +(x * 45), 20,45,45), GUIContent(drops[x].icon,drops[x].Description), skin.customStyles[1])){
if(drops[x].stackAble.Equals(true) && PlayerInventory.Inventory.Contains(drops[x])){
var item = PlayerInventory.Inventory[PlayerInventory.Inventory.IndexOf(drops[x])];
item.Amount += 1;
drops.RemoveAt(x);
}
else
{
PlayerInventory.Inventory.Add(drops[x]);
drops.RemoveAt(x);
}
}
}
if (GUI.Button(Rect(3,3,10,10),"x")){
looting = false;
}
}
function Loot(){
looting = true;
return;
}
my inventory class
#pragma strict
import System.Collections.Generic;
public class PlayerInventory
{
static var Inventory : List.<ItemClass> = new List.<ItemClass>();
}
function Start(){
}
function Update(){
}
And the snippet that deals with the inventory in my levelmanager script.
function Inventory(id : int){
GUI.DragWindow(Rect(0,0,InventoryRect.width,15));
var cnt : int = 0;
for(var x = 0; x < inventoryRows; x++){
for(var y = 0; y < inventoryCols; y++){
if (cnt < PlayerInventory.Inventory.Count){
var texture : Texture2D = PlayerInventory.Inventory[cnt].icon;
var description : String = PlayerInventory.Inventory[cnt].Name + "\n" + PlayerInventory.Inventory[cnt].Description;
if(GUI.Button(Rect(10 + (y * itemWidth ),20 + (x * itemHeight ), itemWidth, itemHeight),GUIContent(texture,description), customSkin.customStyles[1])){
if(PlayerInventory.Inventory[cnt].itemType.Equals(ItemClass.ItemType.Potion) && PlayerInventory.Inventory[cnt].potionType.Equals(ItemClass.PotionType.Heal) && PlayerInventory.Inventory[cnt].Amount > 1){
Health += PlayerInventory.Inventory[cnt].Amount;
PlayerInventory.Inventory[cnt].Amount-= 1;
if(PlayerInventory.Inventory[cnt].Amount == 1){
PlayerInventory.Inventory.RemoveAt(cnt);
}
}
else if(PlayerInventory.Inventory[cnt].itemType.Equals(ItemClass.ItemType.Weapon)){
if(!GetComponent(WeaponManager).WeaponSlot[0].Name.Equals(""))
PlayerInventory.Inventory.Add(GetComponent(WeaponManager).WeaponSlot[0]);
GetComponent(WeaponManager).WeaponSlot[0] =(PlayerInventory.Inventory[cnt]);
PlayerInventory.Inventory.RemoveAt(cnt);
}
else{
PlayerInventory.Inventory.RemoveAt(cnt);
}
}
}
else{
GUI.Box(Rect(10 + (y * itemWidth ),20 + (x * itemHeight ), itemWidth, itemHeight),"", customSkin.customStyles[0]);
}
cnt++;
}
}
}
I'm not looking for a system all coded out, or I would have already done that. I like the way my system works, and the fact I made it. this is the first time I've come to the answers community and I hope I can learn something here. Any help would be appreciated :)
Answer by Bunny83 · Aug 18, 2012 at 01:55 AM
Well there are some things i would change ;)
First the boolean is redundant. Since you have a MaxStack variable you can simply set it to 0 or -1 for items that aren't stackable.
Next thing is how can you tell that two items are of the same type? ItemID? Name? You have to specify a criteria which you can use to identify similar items.
I would probably create a filter function. Something like that:
public class PlayerInventory
{
static var Inventory : List.<ItemClass> = new List.<ItemClass>();
static function FilterItems(ID : int) : List.<ItemClass>
{
var result = new List.<ItemClass>();
for(var item : ItemClass in Inventory)
{
if (item.ItemID == ID && item.Amount < item.maxStack)
result.Add(item);
}
return result;
}
}
// [...]
for( var x : int = 0; x< drops.Count; x++)
{
if(GUI.Button(Rect(10 +(x * 45), 20,45,45), GUIContent(drops[x].icon,drops[x].Description), skin.customStyles[1]))
{
if( drops[x].maxStack > 0)
{
var stacks = PlayerInventory.FilterItems(drops[x].ItemID);
if (stacks.Count > 0)
{
stacks[0].Amount++;
drops.RemoveAt(x);
x--; // Since we removed this one
}
else // when there is no stack yet or all stacks are full, add a new one
{
PlayerInventory.Inventory.Add(drops[x]);
drops.RemoveAt(x);
x--;
}
}
else
{
PlayerInventory.Inventory.Add(drops[x]);
drops.RemoveAt(x);
x--;
}
}
}
Note: I just wrote / modified that here on UA so there might be some syntax errors ;)
I just compared the ItemID in this case. Maybe you want something else?!
You are brilliant. This worked like a dream, albeit with some modification to my inventory managing but it worked out perfectly. This is where I was trying to go with my script, but I had no idea how to approach this. Thank you very much for showing me.
Answer by Paulo-Henrique025 · Aug 18, 2012 at 02:20 AM
Take a look, maybe you can do something like this(C# Code):
public class Items
{
public int life;
public int price;
public int weight;
}
//Creating our List
public List<Items> inventory = new List<Items>();
void Start()
{
//Creating some items to put in the list
Items potion = new Items();
potion.life = 50;
potion.price = 70;
potion.weight = 10;
Items sword = new Items();
sword.life = 150;
sword.price = 350;
sword.weight = 100;
//Adding them to the list
inventory.Add(potion);
inventory.Add(sword);
//Searching for the sword
foreach (Items i in inventory)
{
if(i == sword)
{
Debug.Log(i.price); //Loging the current price
i.price = 8001; // Chanching the proce
}
}
Debug.Log(sword.price); // Loging the swrod price to double check our implementation works!
}
}
(Tested)
Your answer
Follow this Question
Related Questions
Unity C# - Foreach loop - Inventory slot only changes quantity for the last child of an object 1 Answer
How to make an inventory for my text advenutre? 0 Answers
How to set up a gui text box to count inventory items? 1 Answer
Equipting a Item/Weapon 1 Answer
Database error updating inventory 0 Answers