I'm having a hell of a time here.

This code is giving me some Errors.

CS0118: Line 86: 'Server.Gumps.AccountDBoxGump' is a 'type' but is used like a 'variable'
CS0103: Line 86: The name 'Buttons' does not exist in the current context
CS0118: Line 92: 'Server.Gumps.AccountDBoxGump' is a 'type' but is used like a 'variable'
CS0103: Line 92: The name 'Buttons' does not exist in the current context

Code:
				player.SendGump(new AccountDBoxGump(player));
				if (AccountDBoxGump(player).Buttons == Buttons.Okay)//Line 86
				{
					this.m_Account = from.Account.Username;
					this.Hue = 0x482;
					this.Name = from.Name.ToString() + "'s Account Deposit Box";
				}
				else if (AccountDBoxGump(player).Buttons == Buttons.Cancel)//Line 92
				{
					return;
				}

The above section is in my OnDoubleClick.

I tried to do the similar thing in the actual gump button option.

Code:
        public override void OnResponse(NetState sender, RelayInfo info)
        {
			AccountDepositBox adbox = new AccountDepositBox();
            Mobile from = sender.Mobile;
            switch(info.ButtonID)
            {
                case (int)Buttons.Okay:
				{
					Item[] Token = sender.Mobile.BankBox.FindItemsByType( typeof( Gold ) );
					if ( sender.Mobile.BankBox.ConsumeTotal( typeof( Gold ), 50000 ) == true )
					{
/*Dosnt Work*/			adbox.m_Account = sender.Mobile.Account.Username;//Will not change Chest props
/*Dosnt Work*/			adbox.Hue = 0x482;//Will not change Chest props
/*Dosnt Work*/			adbox.Name = sender.Mobile.Name.ToString() + "'s Account Deposit Box";//Will not change Chest props
						Timer adbox_timer = new AccountDBoxTimer(adbox, sender.Mobile);
						adbox_timer.Start();
						//sender.Mobile.SendMessage("You successfully bought use of this Account Deposit Box!");
						//sender.Mobile.SendMessage("This Account Deposit Box is now linked to all characters on this account.");
/*Debug Line*/			Console.WriteLine("Timer has Started");
					}
					else
					{
						//sender.Mobile.SendMessage( "You do not have enough gold in the bank to purchase the Account Deposit Box." );
/*Debug Line*/			Console.WriteLine("Nothing Will Happen");
					}
					break;
				}
				case (int)Buttons.Cancel:
				{
					sender.Mobile.SendMessage("You decide against buying use of this Account Deposit Box.");
/*Debug Line*/		Console.WriteLine("Answer No");
					sender.Mobile.CloseGump(typeof(AccountDBoxGump));
					break;
				}
            }
        }

But the above does not change any props in the Account Box.

Any suggestions/Help with this will be greatly appreciated.
I've been having troubles for a While with this.
 

Attachments

  • AccountDepositBox1_2.cs
    8.2 KB · Views: 4
Also, Should I be using something other than a timer here?

Someone suggested using DateTime, but I'm not even sure how that works.
I barely understand timers.
 
Of the bat what I notice is your use of
if (AccountDBoxGump(player).Buttons == Buttons.Okay)

This is an enumeration inside your gump, and it won't ever be equal to one of its enumerations.

It's more like:

Code:
if(info.ButtonID == (int)Buttons.Okay)

But even that is within the OnResponse override within the gump, which is where you'll need to check it.

What you could do is give the gump itself like a ButtonSelected variable as a Buttons enum type that is set on your gump response, and then make it public so you can access it from your box. But even then, you'll need a reference to the gump object itself.

Upon further investigation it looks like the problem you were trying to solve is that the gump itself is not affecting the box - it's because you're creating a new object within the gump instead of passing the box object via parameter on construction of the gump.
 
Last edited:
(Double posted so you'd get an alert)
Try something like this:


Code:
//In Box
public override OnDoubleClick(Mobile from)
{
	from.CloseGump(typeof(ValidatePurchaseGump));
	from.SendGump(new ValidatePurchaseGump(this));
}

//In Gump

AccountDepositBox box;

//C-tor
public ValidatePurchaseGump(AccountDespositBox b)
{
	box = b;
}

public override void OnResponse(Netstate sender, RelayInfo info)
{
	box.Hue = 1;
}
 
Thank you, That helped out ALOT.

Now i have another question.

How would I use MoveToWorld to move all the items in the Chest to the ground when renewal gets canceled

find items in chest then
MoveToWorld(box.Location, box.Map)

I was trying to move everything to the players bank before i wanted to drop the items, but was getting an ArrayList issue.

Code:
						ArrayList boxitems = new ArrayList(box.Items);
						foreach (Item item in box)
						{
							if ((item.Layer != Layer.Bank) && (item.Layer != Layer.Backpack) && (item.Layer != Layer.Hair) && (item.Layer != Layer.FacialHair) && (item.Layer != Layer.Mount))
							{
								bankbox.DropItem(item);
							}
						}
CS0246: Line 307: The type or namespace name 'ArrayList' could not be found (are you missing a using directive or an assembly reference?)
CS0246: Line 307: The type or namespace name 'ArrayList' could not be found (are you missing a using directive or an assembly reference?)
CS1579: Line 308: foreach statement cannot operate on variables of type 'Server.Items.AccountDepositBox' because 'Server.Items.AccountDepositBox' does not contain a public definition for 'GetEnumerator'
 
Last edited:
First off, ArrayLists shouldn't be used, really in any circumstances (unless in the effort to maintain backwards compatability with pre .Net 2.0). These were used before the existence of generics.

See: http://www.codeproject.com/Tips/531893/For-Vs-Foreach-Benchmark

You'll want a list, or an array. Generally a list is the way to go, unless you're not going to be resizing it and know exactly how many elements you'll need. In which case, you'd use an array.

As to why the code doesn't work, you'll want to use the AcquireItems() method.

Code:
foreach (Item item in ((Container)box).AcquireItems())
 
Code:
foreach (Item item in ((Container)box).AcquireItems())

Okay, That compiles but when i hit cancel with an item in the chest, The server craps this out in a crash report...

Code:
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
   at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
   at Server.Gumps.AccountDBoxRenewGump.OnResponse(NetState sender, RelayInfo info) in c:\Users\JBob\Desktop\ServUOmaster\Scripts\custom\AccountDepositBox1_2.cs:line 344
   at Server.Network.PacketHandlers.DisplayGumpResponse(NetState state, PacketReader pvSrc) in c:\Users\JBob\Desktop\ServUOmaster\Server\Network\PacketHandlers.cs:line 1367
   at Server.Network.MessagePump.HandleReceive(NetState ns) in c:\Users\JBob\Desktop\ServUO-master\Server\Network\MessagePump.cs:line 303
   at Server.Network.MessagePump.Slice() in c:\Users\JBob\Desktop\ServUO-master\Server\Network\MessagePump.cs:line 121
   at Server.Core.Main(String[] args) in c:\Users\JBob\Desktop\ServUO-master\Server\Main.cs:line 624

The line you posted what the line that threw the error.
 
What does the cancel button do?

++Nevermind. I don't think it's your cancel button..

Can you post your updated code?
 
Last edited:
I now have two gumps, The first one when the chest is unowned, and the second is a renewal gump.
in the timer it checks if the player is online or not.
If they are offline it looks threw the players bank for money, if 50k is found, the timer takes the money and continues the "subscription" as it were. and if no money was found put everything in bank

If the player is online the timer will send the renewal gump, the okay button looks for money in the bank and takes it if present. if not it will cancel the "subscription" and reset the chest for someone else to buy and put everythign in the bank.
If the player hits cancel to the renewal gump it will put everything in the players bank and reset the chest.
 
The crash is due to the foreach functionality acting on the AcquireItems() list, i'll have to do some further investigation to really tell you why though.

Change it to this and you should be good.

Code:
                    for (int i = 0; i < ((Container)box).AcquireItems().Count; i++)
                    {
                        sender.Mobile.BankBox.DropItem(((Container)box).AcquireItems()[i]);
                    }
 
For everyone's future reference:

When using a foreach statement, you may not use AcquireItems() within the control statement. The reason being, every time it iterates through it's generating a new list. This is a problem because you're enacting a loop on the list that existed beforehand.

The solution? Commit the results of Container.AcquireItems() to list, and then iterate through that list.

Code:
List<Item> items =  Container.AcquireItems();

foreach(Item i in items)
{
}

Also, @JBob - the code I provided is not in line with good practice apparently. Even when using a for loop, it is not recommended you acquire the list within the control statement.

Code:
int count = Container.AcquireItems().Count;

for(int i = 0; i < count; i++)
{
}
 
Code:
					#region Move Items to Bank
					//Crashes The Server
					int count = ((Container)box).AcquireItems().Count;
                    for (int i = 0; i < count; i++)
                    {
                        sender.Mobile.BankBox.DropItem(((Container)box).AcquireItems()[i]);
                    }
					#endregion

Code:
					#region Move Items to Bank
					//Dosnt Move All The Items
					for (int i = 0; i < ((Container)box).AcquireItems().Count; i++)
					{
						sender.Mobile.BankBox.DropItem(((Container)box).AcquireItems()[i]);
					}
					#endregion

The first section gives an error on this line

sender.Mobile.BankBox.DropItem(((Container)box).AcquireItems());

The second section does not move all the items from the container to the bank.

This section below crashes the server also. It seems to be crashing from the line that tries to send the items to the bank on all but the middle section of codes.

Code:
					#region Move Items to Bank
					int count = box.AcquireItems().Count;
					for(int i = 0; i < count; i++)
					{
						sender.Mobile.BankBox.DropItem((box).AcquireItems()[i]);
					}
					#endregion

I'm getting lost here.(Not Enough Script Exp to grasp all of this.)
 
This is the crashlog i got
Code:
   at System.Collections.Generic.List`1.get_Item(Int32 index)
   at Server.Gumps.AccountDBoxRenewGump.OnResponse(NetState sender, RelayInfo info) in c:\ServUOmaster\Scripts\custom\AccountDepositBox1_2.cs:line 365
   at Server.Network.PacketHandlers.DisplayGumpResponse(NetState state, PacketReader pvSrc) in c:\ServUOmaster\Server\Network\PacketHandlers.cs:line 1367
   at Server.Network.MessagePump.HandleReceive(NetState ns) in c:\ServUO-master\Server\Network\MessagePump.cs:line 303
   at Server.Network.MessagePump.Slice() in c:\ServUO-master\Server\Network\MessagePump.cs:line 121
   at Server.Core.Main(String[] args) in c:\ServUO-master\Server\Main.cs:line 624

can you send me the copy that you have working so i can compare?
 
Two hours later...

Okay guys, I'm still not exactly sure why but the "preferred method" crashes.. the method I was using (the one with the list being called in the control statement) works, but only for three items.. which is super weird to me.

Anyway, here's some working code.

Code:
                    List<Item> Items = new List<Item>();

                    foreach (Item item in box.Items)
                        Items.Add(item);

                    for (int x = 0; x < Items.Count; x++)
                        sender.Mobile.BankBox.DropItem(Items[x]);
 
wOOt wOOt! Your the shyt Enroq.

Also for everyone's future reference, you will also need the Assembly Reference...
Code:
using System.Collections.Generic;
Or you will get an error.
 
Hmmm, maybe i could somehow look for the most empty bankbox or something?

Ill be gone most of the day so ill do some more thinking on this
 
Actually, I think Dian was giving you a subtle hint at the solution. You need an IF statement to check the bankbox to see if its full.

Interestingly tho, the script will put the items in the box even if it is full, the problem is when the player takes something out and tries to put something else in (you see this all the time if you use testcenter).
 
Back