I am working on a gump, and I need to assign each of these variables in the foreach() loop.
I tried looping the AddItem statement, but it did not work.
I need to set each variable to item.ItemID as it processes the loop.

Code:
            int b1image = 0;
            int b2image = 0;
            int b3image = 0;
            int b4image = 0;
            int b5image = 0;
            int b6image = 0;
            int b7image = 0;
            int b8image = 0;
            int b9image = 0;
            int b10image = 0;
       
            List<Item> ItemsPack = mPouch.Items;
            int xa = 0;
            foreach (Item item in ItemsPack) // for each of Item item in the pouch.
            {
               AddItem(xa, 10, item.ItemID);
               Console.WriteLine(item.ItemID);
           
               
            }
So, with what I have posted, how can I load the variables i've created during the loop?
Is there a better way to do this?
 
Last edited:
if mPouch is some kind of bag it already is an array and you do not need to assign it to a new list. You can just loop through it. I would also add some debug info like an if (mPouch.count == 0) console.Writeline("the bag is empty"); else { //what you want it to do }

That might help understand where things are going wrong.
 
mPouch is a bag, that's correct. I just don't understand how to assign the variables during a loop. I've been digging for an example in the code, but I haven't found anything that does it this way yet. I'm trying to get the ItemID's and AddItem(x,y,Item.ID) to place them on the Gump.
 
Here is some code I generated for moving shrunken pets out of a person's backpack and into their bank. Maybe it will help

Code:
        public static void BankShrunkenPets(PlayerMobile pm)
        {
            Backpack bag = new Backpack(); bag.Hue = 32;
            ArrayList shrunkenitems = new ArrayList(pm.Backpack.Items);

            // will search the players backpack and move all of the shrinkitems (shrunk pets) and ethereals to their bank box
            foreach (Item item in shrunkenitems)
            {
                if (item is ShrinkItem || item is EtherealMount)
                    bag.DropItem(item);
            }
            if (bag.Items.Count != 0)
                pm.BankBox.DropItem(bag);
            else
                bag.Delete();

            pm.SendMessage("Your shrunken pets and ethereal mounts have been moved to your bank box");
            shrunkenitems.Clear();
        }

Sorry I cannot explain more I am just about to leave for work. I will try and look at it closer if I get free time at work.
 
It's similar to the list I have up there yes. The thing I have no idea how to do is assign the variables while it's iterating over the Items list.
There has to be some way to store them as it's going through the loop. I just don't know how to do it.

EDIT: I am finding out that in C# that you cannot change or update variables during a foreach loop. I am struggling trying to figure out how to do it using a for loop instead.
 
Last edited:
I would think something like this would work. It is hard to tell without seeing the rest of code for the gump

Code:
for (int i = 0; i < mPouch.Length; i++)
{
	console.Writeline(mPouch[i].ItemID);
}

Of course once you are sure the for loop is working you can change the write line to do what you are wanting to do.
 
I get a "Does not contain a definition for .Length" Error.
I've been trying to get .Length to work on the array i've set up too.
But it's just not working.
Code:
----------------------------------------------------------------------------
JustUO - [http://www.playuo.org] Version 2.0
Publish 4
Core: .NET Framework Version 4.0.30319
Core: Optimizing for 8 64-bit processors
Core: Server garbage collection mode enabled
RandomImpl: CSPRandom (Software)
Scripts: Compiling C# scripts...Failed with: 1 errors,  0 warnings

Errors:
+ Custom Systems/Item Hotbar/TheHotBarGump.cs:
    CS1061: Line 95: 'Server.Items.CaptureItemIDPouch' does not contain a defini
tion for 'Length' and no extension method 'Length' accepting a first argument of
type 'Server.Items.CaptureItemIDPouch' could be found (are you missing a using
directive or an assembly reference?)
    CS0021: Line 97: Cannot apply indexing with [] to an expression of type 'Ser
ver.Item'
Scripts: One or more scripts failed to compile or no script files were found.
- Press return to exit, or R to try again.
 
hmm. C# has a .Length and other people have used .Count to get the size of an array.

This is something I will have to look at some time when I am at home PC. Then again I also use a RUNUO 2.4 core and there might be some differences to a ServUO or JustUO core.

If no one else has a solution for you by tomorrow night I will look around and see what I can come up with.
 
Thanks for the help. I also tried .Count as well. I'm not sure if I need to add a using statement for those functions to be called or not. If I do, I have no idea what one to call.
 
Ya, it is something I will need to play with when I get home and have some free time. My work days leave me with minutes at home to look at stuff. I am sure this is something that will get resolved. I know I have looped over lists and collections extracting data or deleting items. I just need to look at specifically how you are wanting to use it.
 
Sorry It took me so long to get back to this, it has been a busy week. I made a command that dumps ItemIDs to the console. This should give you a better idea of how to do this. This worked on my Runuo 2.4.1 build. Hopefully all of this stuff works on your core also.

Note: I did not add very much error checking for bags deleted and such. Be sure to null check and check for deleted stuff in your routine.

Code:
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Gumps;
using Server.Network;
using Server.Mobiles;
using Server.Targeting;

namespace Server.Commands
{
    public class GetItemId
    {
        public static void Initialize()
        {
            CommandSystem.Register("GetID", AccessLevel.Player, new CommandEventHandler(GetID_OnCommand));
        }

        [Usage("GetID")] // Command
        [Description("Gives the ItemIDs of all stuff in a bag to the console.")] // Description
        public static void GetID_OnCommand(CommandEventArgs e)
        {
            Mobile from = e.Mobile;

            from.Target = new BagTarget();
        }

        public class BagTarget : Target
        {
            public BagTarget() : base(1, false, TargetFlags.None)
            {
            }

            protected override void OnTarget(Mobile from, object target)
            {
                if (target is BaseContainer)
                {
                    BaseContainer b = target as BaseContainer;
                    idFromBag(b);
                }
                else
                    from.SendMessage("You must target a container");

            }
        }

        public static void idFromBag(BaseContainer bag)
        {
            List<Item> stuff = bag.Items;

            foreach (Item i in stuff)
            {
                Console.WriteLine(i.ItemID);
            }
        }
    }
}
 
I would do something like this;

C#:
int[] images = new int[ bag.Items.Count ];

for( int i = 0; i < bag.Items.Count; i++ )
{
    images[ i ] = bag.Items[ i ].ItemID;
}

// images is now a list of ItemIDs based on bag.Items
// this replaces the need for named local variables;
// IE, b1image is now images[0] and can be accessed by the relative index (0 to Length-1)

Be wary, though, the images list will be anywhere up to 125 in length due to the container max items.
Also, if you intend to use AddButton and use ItemID's as the button ID's, they won't work, you have to use a normal gump for buttons. However, there is a way around that! You can find a button image that is the right size you need, then overlay it with a tiled image or background so it's hidden, then you add your image over the top of that (AddItem) and it will result in a faux button that can't be differentiated from a normal button unless you're using the Enhanced Client (in which it decides to re-order gump entries based on backgrounds being moved to the back, which would mean your button is in front of the background and looks ugly)
 
Last edited:
I would do something like this;

THIS!!!!! I finally got it to work like this! Thank you for posting this Voxpire!

Saw your edit, and I am already doing something similar. It's working like a charm!

Except...

One follow up question, how would I go about adding a null check to the values that end up empty, like
a default value in the list. I am using the list ID's for buttons in a gump, and I crash if there is nothing to add. So if images[3] doesnt get a value because there are only 2 items in the bag, I need to set SOME value to prevent a out of index error.
 
Last edited:
The initial list that is created with the number of items in length, all the values are defaulted to 0.

You also need to check whether the index you're accessing is within the bounds of the array, it must be 0 -> Length - 1

C#:
int itemID = 0;

if(images.Length > 0) // is it at least 1 in length?
{
	itemID = images[0]; // safe
}

AddItem(0, 0, itemID);

if(images.Length <= 1337)
{
	itemID = images[1337]; // cheese (IndexOutOfRangeException)
}

AddItem(0, 0, itemID);

int random = Utility.Random( 125 ); // returns a random between 0 and 125 (exclusive)

// images contains at least 1 and random is less than the array length?
if(images.Length > 0 && random < images.Length)
{
	itemID = images[random];
}

AddItem(0, 0, itemID);
 
Last edited:
Great! Got it figured out. No more crashing, got an Unused Item ID sitting in the blanks when I load it.

Now, the fun part. Defining what to do with each item type! Thanks for the help you guys!
Here's what it looks like now:
Code:
			int[] images = new int[ 10 ];
			
			for( int a = 0; a < 10; a++)
			{
				if (images[ a ] != 0)
				{
					images [ a ] = 1150;
				}
			}

			for( int i = 0; i < mPouch.Items.Count; i++ )
			{
				images[ i ] = mPouch.Items[ i ].ItemID;
			}
The bag I'm using has a 10 item limit. That saves me some checking too.
One step closer to a working editable hotbar!
 
Back