Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

container functions [solved]

Discussion in 'Scripting' started by gibberingmouther, Nov 21, 2017.

  1. gibberingmouther

    gibberingmouther

    Joined:
    Dec 13, 2016
    Posts:
    259
    EDIT: my code and info about the problem is in the next posts
     
    Last edited: Nov 21, 2017
  2. gibberingmouther

    gibberingmouther

    Joined:
    Dec 13, 2016
    Posts:
    259
    i can provide you more code if you need, but my function (actually both this one and the take all one) doesn't work correctly:
    Code (csharp):
    1.  
    2.  
    3.       public void Container_Transfer(Item item, int qnty)
    4.         {
    5.             //In the script we will remove an item from the inventory
    6.             var found = -1;
    7.             if (item.objname == "Nothing")
    8.                 return;
    9.  
    10.             //We will check if the item exists and take its place
    11.             for (var i = 0; i < containerinv.Length; i++)
    12.             {
    13.                 //ItemID eyedee1 = (ItemID)i;
    14.                 if (containerinv[i].item.objname == item.objname) //maybe have a unique id rather than use name?  possibility.
    15.                 {
    16.                     found = i;
    17.                     break;
    18.                 }
    19.             }
    20.  
    21.             if (found != -1)
    22.             {
    23.                 //If we found the item, we remove it
    24.                 containerinv[found].quantity -= qnty;//qnty is the amount to remove
    25.                 if (containerinv[found].quantity <= 0)
    26.                 {
    27.                     containerinv[found].item = Resources.Load<Item>("Nothing");
    28.                 }
    29.                 //Add item to hero inventory
    30.                 for (var j = 0; j < inventoryref1.inventory.Length; j++)
    31.                 {
    32.                     if (inventoryref1.inventory[j].item = item)
    33.                     {
    34.                         inventoryref1.inventory[j].quantity += qnty;
    35.                         break;
    36.                     }
    37.                     if (inventoryref1.inventory[j].item.objname == "Nothing")
    38.                     {
    39.                         inventoryref1.inventory[j].item = item;
    40.                         inventoryref1.inventory[j].quantity += qnty;
    41.                         break;
    42.                     }
    43.                     if (j == (inventoryref1.inventory.Length - 1))
    44.                     {
    45.                         //quit and print out inventory is full
    46.                     }
    47.                 }
    48.             }
    49.         }
    50.  
     
    Last edited: Nov 21, 2017
  3. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    One thing that can be handy is to have the function return an integer for inventory functions.
    Like, for example, some handy ones might be:
    HowManyOf (item) - returns how many the inv. has.
    CanFit (item) -- tells you how many you could add
    add (item, amount) -- returns an integer saying how many you actually added (may or may not match amount)
    remove --- same as 'add'.

    I don't think you have to check if you're on the last spot in the loop there, unless there is more code not shown, as it would exit automatically..
    You're changing the quantity of one container, but then adjust an inventory by the new amount (is that what you want?)
    You also set the item to nothing twice.
     
    gibberingmouther likes this.
  4. gibberingmouther

    gibberingmouther

    Joined:
    Dec 13, 2016
    Posts:
    259
    i fixed post #2, i didn't have the full function in it. i see what you mean by setting the quantity wrongly, i'll see about fixing that. and btw here's my take all function:
    Code (csharp):
    1.  
    2.        public void Container_Remove_All(Item item)
    3.         {
    4.             //In the script we will remove all items from the inventory
    5.             if (item.objname == "Nothing")
    6.                 return;
    7.  
    8.             // Need a case for item already in inventory
    9.  
    10.             //We will check if the item exists and take its place
    11.             for (var i = 0; i < containerinv.Length; i++)
    12.             {
    13.                 //ItemID eyedee1 = (ItemID)i;
    14.                 if (containerinv[i].item.objname != "Nothing") //maybe have a unique id rather than use name?  possibility.
    15.                 {
    16.                     for (var j = 0; j < inventoryref1.inventory.Length; j++)
    17.                     {
    18.                         if (inventoryref1.inventory[j].item.objname == "Nothing")
    19.                         {
    20.                             inventoryref1.inventory[j].item = item;
    21.                             inventoryref1.inventory[j].quantity += containerinv[i].quantity;
    22.                             containerinv[i].item = Resources.Load<Item>("Nothing");
    23.                             break;
    24.                         }
    25.                         if (j == (inventoryref1.inventory.Length - 1))
    26.                         {
    27.                             //quit and print out inventory is full
    28.                             break;
    29.                         }
    30.                     }
    31.                 }
    32.             }
    33.         }
    34.  

    edit:
    so with my transfer item code, i start out with a healing potion and a sword in the hero's inventory. after i click twice on the container inventory, my hero has two healing potions from the container in his inventory, plus the sword has to all appearances become a healing potion. and i can't get the shield from the container either.
     
    Last edited: Nov 21, 2017
  5. gibberingmouther

    gibberingmouther

    Joined:
    Dec 13, 2016
    Posts:
    259
    sorry for making another post, but i don't want too much text on one post and this thread is already at the top...so not bumping really. here is the other relevant code:
    Code (csharp):
    1.  
    2.        public void OnPointerEnter(PointerEventData eventData)
    3.         {
    4.             theText4.color = Color.red; //Or however you do your color
    5.             Globals.contindex = StringtoIndex(theText4.name);
    6.         }
    7.  
    8.         public void OnPointerClick(PointerEventData eventData)
    9.         {
    10.             if (eventData.button == PointerEventData.InputButton.Left)
    11.             {
    12.                 container1.Container_Transfer(container1.containerinv[Globals.contindex].item, 1);
    13.             }
    14.         }
    15.  
    theText4 is the text this script is attached to. contindex is the array index corresponding to the text inventory slot.

    edit: i should also note, the healing potions go into my inventory no matter which item slot i click on, and the shield doesn't go into my inventory no matter which item slot i click on. kind of weird. i figured this would be easy after doing the stores and whatnot.

    EDIT2: okay, part of the problem was i had a number wrong in the StringtoIndex function, which i didn't put up here. but now i have the shield turning into a healing potion once it's in my inventory. odd.

    edit3: still my take all code doesn't work. going to take a nap then will resume work.
     
    Last edited: Nov 21, 2017
  6. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    OK, what your talking about is basically a bag, with slots to put items.

    So when you are developing something like this, then you should consider building blocks instead of overall methods. I see in your code that your running through lists of stuff trying to find what-not to fill or get spaces. When these methods should be core to your "bag" Do I have a spot available, get me the first available spot... and so on.

    So in this vain I kind of built a simple container like you are doing, but with smaller methods that I can reuse. Hopefully it will make some sense.

    Code (csharp):
    1. // usage:
    2. var bag = new Container(16);
    3.  
    4. public class Container {
    5.     private Item[] items;
    6.     private int size;
    7.     private Item nothing;
    8.  
    9.     public Container(int size){
    10.         this.items = new Item[size];
    11.         this.size = size;
    12.         nothing = new Item ();
    13.         for (var i = 0; i < size; i++) {
    14.             this.items [i] = nothing;
    15.         }
    16.     }
    17.  
    18.     public int Size { get { return size; } }
    19.     public int Available { get {
    20.             var count = 0;
    21.             for (var i = 0; i < size; i++) {
    22.                 if (items [i] == nothing)
    23.                     count++;
    24.             }
    25.             return count;
    26.         } }
    27.  
    28.     public Item Get(string name){
    29.         for (var i = 0; i < size; i++) {
    30.             if (items [i] != nothing && items [i].objname == name)
    31.                 return items [i];
    32.         }
    33.         return nothing;
    34.     }
    35.  
    36.     public int GetEmptyIndex(){
    37.         for (var i = 0; i < size; i++) {
    38.             if (items [i] == nothing)
    39.                 return i;
    40.         }
    41.         return -1;
    42.     }
    43.  
    44.     public int IndexOf(Item item){
    45.         if (item == nothing) {
    46.             return - 1;
    47.         }
    48.         return IndexOf(item.objname);
    49.     }
    50.  
    51.     public int IndexOf(string name){
    52.         for (var i = 0; i < size; i++) {
    53.             if (items [i] != nothing && items [i].objname == name) {
    54.                 return i;
    55.             }
    56.         }
    57.         return -1;
    58.     }
    59.  
    60.     public bool Contains(Item item){
    61.         return Contains(item.objname);
    62.     }
    63.  
    64.     public bool Contains(string name){
    65.         return IndexOf (name) > -1;
    66.     }
    67.  
    68.     public bool Add(Item item){
    69.         if (item == nothing) {
    70.             return false;
    71.         }
    72.         return Add(item.objname, item.qnty);
    73.     }
    74.  
    75.     public bool Add(string name, int qnty){
    76.         var current = Get(name);
    77.         if (current == nothing) {
    78.             var i = this.GetEmptyIndex ();
    79.             if (i == -1) {
    80.                 return false;
    81.             }
    82.             items[i] = new Item{ objname = name, qnty = qnty };
    83.         } else {
    84.             current.qnty += qnty;
    85.         }
    86.         return true;
    87.     }
    88.  
    89.     public void Remove(Item item){
    90.         if (item == nothing) {
    91.             return;
    92.         }
    93.         Remove (item.objname, item.qnty);
    94.     }
    95.  
    96.     public void Remove(string name, int qnty){
    97.         var i = IndexOf(name);
    98.         if (i > -1) {
    99.             var current = items [i];
    100.             current.qnty -= qnty;
    101.             if (current.qnty <= 0) {
    102.                 items [i] = nothing;
    103.             }
    104.         }
    105.     }
    106.  
    107.     public void RemoveAll(Item item){
    108.         if (item == nothing) {
    109.             return;
    110.         }
    111.         RemoveAll(item.objname);
    112.     }
    113.  
    114.     public void RemoveAll(string name){
    115.         var i = IndexOf(name);
    116.         if (i > -1) {
    117.             items[i] = nothing;
    118.         }
    119.     }
    120. }
    121.  
    122. public class Item{
    123.     public string objname { get;set; }
    124.     public int qnty { get; set; }
    125. }

    Now... Just for the fun of it, lets make this into a typable container

    Code (csharp):
    1. // Usage:
    2. var bag = new Container<GameObject>(16);
    3.  
    4. public class Container<T> {
    5.     private Item<T>[] items;
    6.     private int size;
    7.     private Item<T> nothing;
    8.  
    9.     public Container(int size){
    10.         this.items = new Item<T>[size];
    11.         this.size = size;
    12.         nothing = new Item<T>();
    13.         for (var i = 0; i < size; i++) {
    14.             this.items [i] = nothing;
    15.         }
    16.     }
    17.  
    18.     public int Size { get { return this.size; } }
    19.     public int Available { get {
    20.             var count = 0;
    21.             for (var i = 0; i < Size; i++) {
    22.                 if (items [i] == nothing)
    23.                     count++;
    24.             }
    25.             return count;
    26.         } }
    27.  
    28.     public Item<T> Get(string name){
    29.         for (var i = 0; i < size; i++) {
    30.             if (items [i] != nothing && items [i].objname == name)
    31.                 return items [i];
    32.         }
    33.         return nothing;
    34.     }
    35.  
    36.     public int GetEmptyIndex(){
    37.         for (var i = 0; i < size; i++) {
    38.             if (items [i] == nothing)
    39.                 return i;
    40.         }
    41.         return -1;
    42.     }
    43.  
    44.     public int IndexOf(Item<T> item){
    45.         if (item == nothing) {
    46.             return - 1;
    47.         }
    48.         return IndexOf(item.objname);
    49.     }
    50.  
    51.     public int IndexOf(string name){
    52.         for (var i = 0; i < size; i++) {
    53.             if (items [i] != nothing && items [i].objname == name) {
    54.                 return i;
    55.             }
    56.         }
    57.         return -1;
    58.     }
    59.  
    60.     public bool Contains(Item<T> item){
    61.         return Contains(item.objname);
    62.     }
    63.  
    64.     public bool Contains(string name){
    65.         return IndexOf (name) > -1;
    66.     }
    67.  
    68.     public bool Add(Item<T> item, T obj){
    69.         if (item == nothing) {
    70.             return false;
    71.         }
    72.         return Add(item.objname, item.qnty, obj);
    73.     }
    74.  
    75.     public bool Add(string name, int qnty, T obj){
    76.         var current = Get(name);
    77.         if (current == nothing) {
    78.             var i = this.GetEmptyIndex ();
    79.             if (i == -1) {
    80.                 return false;
    81.             }
    82.             items[i] = new Item<T>{ objname = name, qnty = qnty, obj = obj };
    83.         } else {
    84.             current.qnty += qnty;
    85.         }
    86.         return true;
    87.     }
    88.  
    89.     public void Remove(Item<T> item){
    90.         if (item == nothing) {
    91.             return;
    92.         }
    93.         Remove (item.objname, item.qnty);
    94.     }
    95.  
    96.     public void Remove(string name, int qnty){
    97.         var i = IndexOf(name);
    98.         if (i > -1) {
    99.             var current = items [i];
    100.             current.qnty -= qnty;
    101.             if (current.qnty <= 0) {
    102.                 items [i] = nothing;
    103.             }
    104.         }
    105.     }
    106.  
    107.     public void RemoveAll(Item<T> item){
    108.         if (item == nothing) {
    109.             return;
    110.         }
    111.         RemoveAll(item.objname);
    112.     }
    113.  
    114.     public void RemoveAll(string name){
    115.         var i = IndexOf(name);
    116.         if (i > -1) {
    117.             items[i] = nothing;
    118.         }
    119.     }
    120. }
    121.  
    122. public class Item<T>{
    123.     public string objname { get;set; }
    124.     public int qnty { get; set; }
    125.     public T obj { get; set; }
    126. }
    So, some good questions at this point...

    Q: Why use a named type bag with quantities where you are using an object, and not just use a "list" style of just the object?

    A: the object in question may not be the same object as what the previous object in the bag is. It could, have the same name, and you could differentiate that way, but you then would not have a quantity) Its just a little more flexible.

    Q: Could you have the same object in twice, with the same name?

    A: No, the objects are differentiated by name, so they should be unique in that respect.

    Q: Could you have the same object twice, with different names?

    A: Yes, that is not covered, but that logic is not necessary in this case. It is up to the programmer to either allow, or disallow that.
     
    KelsoMRK and gibberingmouther like this.
  7. gibberingmouther

    gibberingmouther

    Joined:
    Dec 13, 2016
    Posts:
    259
    @bigmisterb will look at your code. that's probably the kind of thing i should be learning from.

    the problem i'm faced with now, with my Container_Transfer method, is that depending on which item i pick up out of the container, it changes my items in my hero inventory into that item type weirdly. need to fix this but not sure how.

    EDIT: aha! was just missing a double equals. still don't have take all working.

    edit2: here's the transfer all code again. i changed it but it still doesn't work correctly. it picked up the shield in the container correctly, but not the two health potions. my hero inventory however went from 2 health potions to 7, even though the 2 potions were still in the container.
    Code (csharp):
    1.  
    2.        public void Container_Transfer_All()
    3.         {
    4.             //In the script we will remove all items from the inventory
    5.  
    6.             //We will check if the item exists and take its place
    7.             for (var i = 0; i < containerinv.Length; i++)
    8.             {
    9.                 //ItemID eyedee1 = (ItemID)i;
    10.                 if (containerinv[i].item.objname != "Nothing")
    11.                 {
    12.                     for (var j = 0; j < inventoryref1.inventory.Length; j++)
    13.                     {
    14.                         if (inventoryref1.inventory[j].item == containerinv[i].item)
    15.                         {
    16.                             inventoryref1.inventory[j].quantity += containerinv[i].quantity;
    17.                             break;
    18.                         }
    19.                         if (inventoryref1.inventory[j].item.objname == "Nothing")
    20.                         {
    21.                             inventoryref1.inventory[j].item = containerinv[i].item;
    22.                             inventoryref1.inventory[j].quantity = containerinv[i].quantity;
    23.                             containerinv[i].item = Resources.Load<Item>("Nothing");
    24.                             break;
    25.                         }
    26.                         if (j == (inventoryref1.inventory.Length - 1))
    27.                         {
    28.                             //print out inventory is full
    29.                         }
    30.                     }
    31.                 }
    32.             }
    33.         }
    34.  
    literally there is a "Take All" button at the bottom of my container GUI, and i press that and it is supposed to transfer all the items in the container into my inventory.

    EDIT4: okay, i forgot to assign the container item to nothing in the one if statement. still have one minor problem, i'll bring it up if i can't get it otherwise i'll mark this solved! thanks guys!
     
    Last edited: Nov 21, 2017
  8. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Glad you got it resolved for now.
     
    gibberingmouther likes this.