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 + "

" + 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 :slight_smile:

Well there are some things i would change :wink:

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 :wink:

I just compared the ItemID in this case. Maybe you want something else?!

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)