- Home /
stack by quanity...? C#
[EDIT!]
Well I tryed using a for loop to add to the inventory like so ...
for (int i = 0; i < playerInventory.playerI.Count; i++){
if (playerInventory.playerI[i].itemIndex == ItemType){
playerInventory.playerI[i].quanity++;
}
}
Ok so this works ... well I thought it did till I checked both list and checked them twice!
It keeps the same memory for both list still .... playerI list at element 0 " or dirt " has quanity 2 after two pickups ....
but for some reason the item list however does the same... it has quanity 2 the same as player inventory... im so confused m8's please I love you forever!
HI thank you for viewing this topic!
I've made a inventory based off the berzerg grid inventory system....
The problem im running into is quantity stacking.... I have the method for combining quantity everything fine! However for a quanity max and equipping and de equipping im running into some major problems that seem like they should be easy.....
I'm making a mine craft kinda voxel engine game it works great.... However when I pick up dirt for example I pick up the dirt... adds it to the inventory... and adds to quantity.... Well I figure out that I can use contains... to figure if there is a certain stored item the same as the item index of the dropped mineral..... Sorry about the grammar its kinda hard to explain ....
Basicly I have a public int inside my item class.... and I have a item List class that is attached to the player that hold the index of items derived from Item Class in new list ...
So I had the first idea of actually adding to the itemlist that holds the container for the premade "items" and add to that quanity which worked.. However when equpping dirt for example ... then after equipping it ... I go and dig more dirt ... it adds the same quanity stack.....
So if I dug up 5 dirts...... equipped 5 dirts then grab 1 other dirt ... it adds the new dirt because I have dirt equipped but adds dirt quanity 5 not 1
Here is the method for adding the mineral object.... the mineral object offcourse is generated from index .... so if player hits dirt it passes a new int with something like mineralItem = 0 // if dirt and if sand mineralItem = 1 then it drops the new mineral prefab with a class attached called dropItems that sets its itemType int to = the mineralItem int ....
here is the method for adding the item to the player inventory
public void addItem(){
if (playerInventory.playerI.Contains(itemList.items[ItemType])){
itemList.items[ItemType].quanity ++;
}
else
{
playerInventory.playerI.Add(itemList.items[ItemType]);
}
Destroy(gameObject);
}
And here is the item class it's self....
using UnityEngine;
using System.Collections;
[System.Serializable]
public class Itemclass {
public string _name;
public int _itemIndex;
public Texture2D _itemImage;
public bool _mineral;
public int _typeItem;
public int _quanity;
public int _quanityMax;
public Itemclass()
{
_name = "Unknown";
_itemIndex = 0;
_itemImage = null;
}
public int QuanityMax{
get {return _quanityMax;}
set {_quanityMax = value;}
}
public int quanity{
get { return _quanity; }
set { _quanity = value; }
}
public bool mineral{
get { return _mineral; }
set { _mineral = value; }
}
public int typeItem
{
get { return _typeItem; }
set { _typeItem = value; }
}
public string name{
get { return _name; }
set { _name = value; }
}
public int itemIndex{
get { return _itemIndex; }
set { _itemIndex = value; }
}
public Texture2D itemImage{
get { return _itemImage; }
set { _itemImage = value; }
}
//0 - dirt
//1 - water
//2 - sand
//3 - ice
//4 - grassydirt
public virtual string ToolTip()
{
return name + "\n" + " Type " + itemIndex;
}
}
Finally here is the item list attached to the player ... also the inventory list is stored in a seperate class inventory....
using UnityEngine; using System.Collections; using System.Collections.Generic;
public class Itemlist : MonoBehaviour {
public List<Itemclass> items = new List<Itemclass>();
public Inventory inventory;
// Use this for initialization
void Start () {
for (int i=0; i < items.Count; i++){
//stackItems.Add(1);
}
inventory = gameObject.GetComponent<Inventory>() as Inventory;
}
// Update is called once per frame
void Update () {
}
/*
void addItem(int itemindex){
inventory.playerI.Add(items[itemindex]);
}
*/
}
If you're still reading here is the inventory its kinda messy...
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Inventory : MonoBehaviour {
public GUISkin mySkin;
#region misc
private int oldIndex = -1;
private Itemclass temp2;
public List<Itemclass> playerI = new List<Itemclass>();
public float resW = 0.0f;
public float resH = 0.0f;
private int thirdClick = 0;
private Itemclass weaponEQ;
private bool mineralEQ;
public int stackI = 0;
private Itemclass openWeapon ;
public bool MineralEQ
{
get {return mineralEQ;}
set {mineralEQ = value;}
}
public Itemclass WeaponEQ
{
get {return weaponEQ;}
set {weaponEQ = value;}
}
#endregion
#region inventory params
public float invX = 0.0f;
public float invY = 0.0f;
public float invWidth = 0.0f;
public float invHeight = 0.0f;
private Rect inventoryBox;
public float backgroundHeight = 0.0f;
public Vector3 scale;
public float btnX = 0.0f;
public float btnY = 0.0f;
public float buttonWidth = 0.0f;
public float buttonHeight = 0.0f;
private Rect gridBox;
public int inventorySize = 10;
private int currentInventorySize = 0;
private int invSX;
private int invSY;
private Matrix4x4 svMat;
#endregion // This block of code displays inventory paramaters that are needed to adjust the gui inventory
#region char params
public float charX = 0.0f;
public float charY = 0.0f;
public float charWidth = 0.0f;
public float charHeight = 0.0f;
private Rect charBox;
public float charbuttonX = 0.0f;
public float charbuttonY = 0.0f;
private int _characterPanel = 0;
private string[] _characterPanelNames = new string[] { "Equipment", "Stats" , "Skills" };
private float _doubleClickTimer = 0;
private const float _DoubleClickTimer = 0.2f;
private Itemclass _selectedItem;
public int[] itemCAP;
#endregion // This block of code is the public parameter for the character GUI
#region display properties
private Texture2D[] itemIcon;
public int selGridInt = 0;
private string[] inventoryNames;
private Vector2 mousePos;
#endregion // This block of code contains image value arrays and assorted.
#region Scripts to grab
public PlayerIO playerinventory;
public MouseLook mainCam;
public MouseLook mainCam2;
public FPSInputController moveCon;
#endregion // This offcourse is self explained needs only to be grabbed.
#region inventory slots init
#endregion
private string _toolTip = "";
//public int[] inventoryMax = new array();
//32
// Use this for initialization
void Start () {
//invSX = inventorySize / 2;
//invSY = inventorySize / 2;
//Debug.Log(invSX);
float resoX = Screen.currentResolution.width;
float resoY = Screen.currentResolution.height;
svMat = GUI.matrix; // save current matrix
scale = new Vector3(Screen.width/resoX, Screen.height/resoY,0);
#region main calls to the inventory
// This stores the windows resoultion ...
inventoryBox = new Rect(Screen.width/invX, Screen.height/invY, Screen.width/invWidth, Screen.height/invHeight);
gridBox = new Rect(Screen.width/(invX+40), Screen.height/(invY+20), Screen.width/(invWidth + 0.5f ), Screen.height/(invHeight + 0.5f ));
charBox = new Rect(Screen.width/charX, Screen.height/charY, Screen.width/charWidth, Screen.height/charHeight);
//beltBox = new Rect(Screen.width/charX, Screen.height/charY, Screen.width/charWidth, Screen.height/charHeight);
//Debug.Log(gridBox);
//inventoryNames = new string[items.Count];
mainCam = GameObject.FindGameObjectWithTag("Player").GetComponent<MouseLook>() as MouseLook;
mainCam2 = gameObject.GetComponent<MouseLook>() as MouseLook;
playerinventory = gameObject.GetComponent<PlayerIO>() as PlayerIO;
#endregion
}
// Update is called once per frame
void Update () {
openWeapon = weaponEQ;
#region pause screen character inventory etc.
if (Screen.showCursor == true){
//mousePos = Event.current.mousePosition;
mainCam.enabled = false;
mainCam2.enabled = false;
moveCon.enabled = false;
}
else
{
mainCam.enabled = true;
mainCam2.enabled = true;
moveCon.enabled = true;
}
#endregion
}
void OnGUI (){
GUI.skin = mySkin;
//GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, scale);
#region pause screen menue inventory etc ....
GUI.skin.button.wordWrap = true;
if (Screen.showCursor == true){
Vector2 scrollPos = new Vector2(Screen.width / 2 * invX , Screen.height/2 * invY);
//GUI.Box(inventoryBox,"");
inventoryBox = GUI.Window(0,inventoryBox,inventoryGrid, " Inventory ");
charBox = GUI.Window(1,charBox,charWindow, " Character ");
DisplayToolTip();
}
#endregion
//GUI.matrix = svMat;
}
public void inventoryGrid(int windowID)
{
int cnt = 0;
#region Block cells for inventory
GUI.Box(gridBox,"bob");
for (int x = 0 ; x < inventorySize; x ++ ){
for (int y = 0; y < inventorySize; y++){
if (cnt < playerI.Count){
if (GUI.Button(new Rect(gridBox.x + x * gridBox.width /(inventorySize), gridBox.y + y * gridBox.height/(inventorySize),gridBox.width /(inventorySize),gridBox.height/(inventorySize)),new GUIContent(playerI[cnt].name,playerI[cnt].ToolTip()))){
if ((_doubleClickTimer != 0) && (_selectedItem != null)){
if (Time.time - _doubleClickTimer < _DoubleClickTimer){
Debug.Log("Double Clicked");
_doubleClickTimer = 0;
_selectedItem = null;
if (weaponEQ == null){
weaponEQ = playerI[cnt];
playerI.RemoveAt(cnt);
}
else
{
Itemclass temp = weaponEQ;
weaponEQ = playerI[cnt];
playerI[cnt] = temp;
}
}
else
{
Debug.Log("reset timer");
if (playerI[oldIndex].itemIndex != playerI[cnt].itemIndex){
temp2 = playerI[cnt];
playerI[oldIndex] = temp2;
playerI[cnt] = _selectedItem;
_selectedItem = null;
_doubleClickTimer = 0;
//temp2 = playerI[oldIndex];
}
else
{
int storedQ = playerI[cnt].quanity + playerI[oldIndex].quanity;
if (storedQ < playerI[cnt].QuanityMax){
playerI[cnt].quanity = Mathf.Clamp(playerI[cnt].quanity + playerI[oldIndex].quanity,0,100);
playerI.RemoveAt(oldIndex);
}
}
//Debug.Log(oldIndex);
}
}
else
{
_doubleClickTimer = Time.time;
if (_selectedItem == null){
_selectedItem = playerI[cnt];
}
oldIndex = cnt;
}
}
if (cnt < playerI.Count){
GUI.Box(new Rect(gridBox.x * 1.8f + x * gridBox.width /(inventorySize), gridBox.y * 1.5f + y * gridBox.height/(inventorySize),gridBox.width /(inventorySize * 2.1f) ,gridBox.height/(inventorySize * 2f)) ,new GUIContent(playerI[cnt].quanity.ToString()));
}
}
else
{
GUI.Label(new Rect(gridBox.x + x * gridBox.width /(inventorySize), gridBox.y + y * gridBox.height/(inventorySize),gridBox.width/(inventorySize),gridBox.height/(inventorySize)),"","box");
}
cnt ++;
}
}
#endregion
SetToolTip();
GUI.DragWindow ();
}
void charWindow(int windowID){
_characterPanel = GUI.Toolbar(new Rect(5,25, charBox.width - 10, 25),_characterPanel,_characterPanelNames);
switch (_characterPanel)
{
case 0:
equipScreen();
break;
case 1:
statsScreen();
break;
case 2:
skillsScreen();
break;
}
//GUI.DragWindow();
}
private void equipScreen(){
GUI.Button(new Rect(charBox.x/4f,charBox.y/0.5f,charBox.width / 4,charBox.height / 4.5f),"Head");
if (weaponEQ == null){
GUI.Box(new Rect(charBox.x/15f,charBox.y/0.21f,charBox.width / 4,charBox.height / 4.5f),"Weapon");
}
else
{
if (GUI.Button(new Rect(charBox.x/15f,charBox.y/0.21f,charBox.width / 4,charBox.height / 4.5f),new GUIContent(weaponEQ.name,weaponEQ.ToolTip()))){
playerI.Add(weaponEQ);
weaponEQ = null;
}
}
GUI.Button(new Rect(charBox.x/2.18f,charBox.y/0.21f,charBox.width / 4,charBox.height / 4.5f),"shield");
GUI.Button(new Rect(charBox.x/4f,charBox.y/0.21f,charBox.width / 4,charBox.height / 4.5f),"Body");
GUI.Button(new Rect(charBox.x/4f,charBox.y/0.13f,charBox.width / 4,charBox.height / 4.5f),"Legs");
//GUI.DragWindow();
SetToolTip();
}
private void statsScreen(){
}
private void skillsScreen(){
}
private void SetToolTip(){
#region event function
if (Event.current.type == EventType.Repaint && GUI.tooltip != _toolTip){
if (_toolTip != ""){
_toolTip = "";
}
if (GUI.tooltip != ""){
_toolTip = GUI.tooltip;
}
}
#endregion
}
private void DisplayToolTip(){
#region tool tip function
mousePos = Event.current.mousePosition;
if (_toolTip != ""){
//GUI.Box(new Rect(Screen.width /4f , Screen.height /7 , 400 , 200),_toolTip);
GUI.Box(new Rect(mousePos.x , mousePos.y, 250 , 200),_toolTip);
}
#endregion
}
}
Answer by DESTRUKTORR · Aug 29, 2013 at 10:14 PM
There's a number of issues here. Firstly, contains uses the object's defined qualifier for the Equals method, for that class. You have not overridden the Equals method, and thus they will use the default implementation that is developed in the System.Object class (from which every class you will ever make inherits, through whatever chain of inheritance it uses), which only checks to see if it is EXACTLY the same object, and not a "similar" object.
To explain in simpler terms, unless you change the equality comparer that the list will use (most simply accomplished, in my opinion, by overriding the Equals and the GetHashCode methods from System.Object), using "contains" will only return if the EXACT object you're searching for is contained in that list.
Additionally, when you actually call the "Add" method, in the "else" block in the first piece of script you have pasted, up there, you call it like this:
playerInventory.playerI.Add(itemList.items[ItemType]);
The issue here is that the parameter you're using is the object that is already contained in the itemlist, of that type. Additionally, when you changed the "quantity" variable for the item, the item in the "itemList" had its quantity changed, as well, because you were using a reference to the same object.
Honestly, your inventory system seems pretty over-complicated to fully debug, right now, but I would start by finding a better way of checking if the inventory already has a specific item in it.
Hint: All "contains" does for a standard list is to loop through it, object-by-object and check each one against the object being searched for. You could very easily create a similar loop, yourself, and just use a simple conditional based on some manner of id that is unique to the item, to check if that item type is contained in the list.
[Edit] You'll also probably want to ensure that when you add a new item stack to the inventory that you make a duplicate object of the one in the itemlist, and don't actually edit the items in the itemlist, by editing the references that point back to their respective objects.
Thanks DESTRU$$anonymous$$TORR
I figured as much with the contains before but was not able to wrap my head around it ... I should be able to create a simple for loop for just that .... However Im still stuck here ... I mean it works with the contain when adding new items from the itemlist
for example if I get dirt and its in inventory and I get a new dirt it will just stack quanity not add 2 dirt items...
The problem though is the item list quanity is 2 and inventory list is 2
Well i dont understand what you mean by using the same element here...
If I have 2 seperate list ..... I only add to the inventory list of the index item list... which for example I have 4 in the item list dirt, sand , rock , wood
Now these are pre made and are public in the class itemlist
However I want to add from the indexed item list
like dirt.....
So I reference the indexed dirt ... like so
playerInventory.playerI.Add(itemList.items[ItemType]);
This grabs the object itemlist and its items < list > with index of the current dropped item "dirt, sand , rock, etc"
then adds it to the playerinventory list so if its sand then the first element would be sand....
it only does this if there is no duplicated of the dropped item
otherwise "else"
add to the quanity of the player inventory list
What im not understanding is why do both of the list change there quanity as itemlist is only the reference to items.?!
If I were to create duplicates all there elements would contain the same quanity.... I have no clue how to add seperate quanities to different list....?
To try to explain this again .... for example for my inventory class lets say I create the new list which was playerI
Now in the unity editor I add the size 1 ... just one item ... ( just for an example of what I dont understand here )
then in the start function of the inventory object ...
I say that playerI[0].quanity = 3;
if I run the game the first element or player[0] its quanity = 3 and the item list is untouched....?
how come the itemlist is adding from the dropped item... and the quanity of the player I .... its confusing to me?! sorry about this mess.
playerInventory.playerI.Add(itemList.items[ItemType]);
That line of code refers to an object you named "itemList" which I can only assume is supposed to refer to a static list of all the game's item types. However, the issue here, as it seems, is that when this is called, the stack quantity has already been set to 5 for the specific item in that list, as you stated was one of your primary issues, in the original question.
The only reasonable explanation for this would be that this static list that is used to reference items by their type index ("`ItemType`" in "`itemList.items[ItemType]`") has had its members edited somewhere along the way, as the default value for Quantity should be 0 (based on the way you've laid out your classes, here, though you may want to set that default value to 1, by declaring it like so: "`quantity = 1`" -without the quotes-, as it wouldn't make sense to have an item in your inventory with quantity 0, as its object should have been destroyed or somehow re-collected from your inventory, if that were the case).
If you're going to use this static list model for items in your game, you will want to ensure that the objects within that list are not edited.
If you've got no idea what I'm talking about with the whole "static list" thing, and you didn't want to have a list of item references to pull from when managing items of various types, then you shouldn't use "`playerInventory.playerI.Add(itemList.items[ItemType]);`" <- that. You should use something that creates a new object of Itemclass (which you did not paste the code for, and would seriously change how that would need to happen, depending on whether or not it inherited from $$anonymous$$onoBehaviour).
However, it is not a bad model to use a static list for item management, as it allows you to quickly and easily check items by a simple id. Just keep in $$anonymous$$d that you'l need to either instantiate a new object of the item's type, or (in the case that Itemclass inherits from $$anonymous$$onoBehaviour) instantiate the proper prefab, or create a new GameObject and attach an Itemclass component to it, setting the proper values to the behaviour.
AH! Thanks dear watson ! Seriously thank you though that was a good explanation I was just about to code out a correct method of using a loot which adds to its own item list that pulls out a new Item from the static item generator... .... mmm the only thing im wondering is how to pull the list into the new object... should not be to difficult ... So :) Thanks sir!
I was wondering if it was referencing the static class and just listing i was thinking they worked like array types.... list have been new to me for the past year they still confuse yet they simply 4 hours of code sometimes...
Sincerely, jake
Answer by Indiegangster · Aug 30, 2013 at 04:39 AM
Anyone is interested still I wrote up a strange method in my add item method to check if an item contains the itemindex or " ID " if so it does an operator check then adds or subtracts here it is ....
int itemT = 0;
for (int a = 0; a < playerInventory.playerI.Count; a ++){
if (playerInventory.playerI[a].itemIndex == ItemType){
itemT = 1;
}
}
if (itemT == 0){
playerInventory.playerI.Add(loot[0]);
}
else
{
for (int i=0; i < playerInventory.playerI.Count; i++){
if (playerInventory.playerI[i].itemIndex == ItemType){
playerInventory.playerI[i].quanity ++;
break;
}
}
}
I would suggest learning a different method but this a real simpleton if you will on how to loop out... with this one ..
[EDIT!]
Actually excuse me I finally figured out how to use findIndex that should ... work much better then the pervious solution ...
int index = playerInventory.playerI.FindIndex(item => item.itemIndex == ItemType);
if (index != 0){
#region This block set creates new mineral Items
Itemclass newItem = new Itemclass();
newItem.name = itemList.items[ItemType].name;
newItem.itemIndex = itemList.items[ItemType].itemIndex;
newItem.itemImage = itemList.items[ItemType].itemImage;
newItem.mineral = itemList.items[ItemType].mineral;
newItem.typeItem = itemList.items[ItemType].typeItem;
newItem.quanity = itemList.items[ItemType].quanity;
newItem.QuanityMax = itemList.items[ItemType].QuanityMax;
#endregion
playerInventory.playerI.Add(newItem);
}
else
{
for (int i=0; i < playerInventory.playerI.Count; i++){
if (playerInventory.playerI[i].itemIndex == ItemType){
playerInventory.playerI[i].quanity ++;
break;
}
}
}