tass23

Member
Awhile back an issue was addressed on my shard where Vendors were removing gold from Alpha's Gold Ledger AND a Player's bankbox (duplicate withdrawals). Thinking the problem had been solved, I haven't given it much thought. However, a player recently reported that vendors would not sell items at all. A message was appearing stating that XX gold was withdrawn from your (backpack/ledger/bankbox), but it wasn't actually happening. So I took a look at the script for BaseVendor and this was the fix that was put into place:
Code:
                if (buyer.Backpack != null)
                {
                    Item item = buyer.Backpack.FindItemByType(typeof(GoldLedger));
                    GoldLedger ledger = item as GoldLedger;
                    Item[] item2 = buyer.Backpack.FindItemsByType(typeof(Gold));

                    int goldint = 0;
                    foreach (Item item3 in item2)
                        goldint += item3.Amount;
                    if (buyer.Backpack.ConsumeTotal(typeof(Gold), totalCost))
                    {
                        if (Core.Debug) buyer.SendMessage(2125, "{0} gold has been withdrawn from your backpack.", totalCost.ToString("#,0"));
                        bought = true;
                    }
                    else if (ledger != null)
                    {
                        if (goldint > 0 && (goldint + ledger.Gold) >= totalCost)
                        {
                            buyer.Backpack.ConsumeTotal(typeof(Gold), goldint);
                            if (Core.Debug) buyer.SendMessage(2125, "{0} gold was taken from your backpack.", goldint.ToString("#,0"));
                            ledger.Gold -= (totalCost - goldint);
                            if (Core.Debug) buyer.SendMessage(2125, "The balance of {0} gold was withdrawn from your gold ledger.", (totalCost - goldint).ToString("#,0"));
                            bought = true;
                            fromLedger = true;
                        }
                        else if (ledger.Gold >= totalCost)
                        {
                            ledger.Gold -= totalCost;
                            if (Core.Debug) buyer.SendMessage(2125, "{0} gold has been withdrawn from your gold ledger.", totalCost.ToString("#,0"));
                            bought = true;
                            fromLedger = true;
                        }
                    }
                }

Now onto the "fun" part. What I have discovered is that if a player HAS a Gold Ledger, but it has no gold in it, vendors will not sell the player anything, but the player will still get the message the gold has been withdrawn from (backpack/ledger/bankbox). I'm assuming at this point I'm going to have to add an additional Else If statement to cover a Gold Ledger that has no gold...correct?

EDIT:
I've added another Else If statement to withdraw the gold from the player's bankbox and it does work (but it has to be loose gold, checks are ignored) and if the player has NO loose gold in their bankbox, the purchase list stays on their screen and they get no message that they are lacking the funds. So it seems that no matter what, I'm getting hung up in this loop. Here is the code with the new section:
Code:
                if (buyer.Backpack != null)
                {
                    Item item = buyer.Backpack.FindItemByType(typeof(GoldLedger));
                    GoldLedger ledger = item as GoldLedger;
                    Item[] item2 = buyer.Backpack.FindItemsByType(typeof(Gold));

                    int goldint = 0;
                    foreach (Item item3 in item2)
                        goldint += item3.Amount;
                    if (buyer.Backpack.ConsumeTotal(typeof(Gold), totalCost))
                    {
                        if (Core.Debug) buyer.SendMessage(2125, "{0} gold has been withdrawn from your backpack.", totalCost.ToString("#,0"));
                        bought = true;
                    }
                    else if (ledger != null && ledger.Gold != 0)
                    {
                        if (goldint > 0 && (goldint + ledger.Gold) >= totalCost)
                        {
                            buyer.Backpack.ConsumeTotal(typeof(Gold), goldint);
                            if (Core.Debug) buyer.SendMessage(2125, "{0} gold was taken from your backpack.", goldint.ToString("#,0"));
                            ledger.Gold -= (totalCost - goldint);
                            if (Core.Debug) buyer.SendMessage(2125, "The balance of {0} gold was withdrawn from your gold ledger.", (totalCost - goldint).ToString("#,0"));
                            bought = true;
                            fromLedger = true;
                        }
                        else if (ledger.Gold >= totalCost)
                        {
                            ledger.Gold -= totalCost;
                            if (Core.Debug) buyer.SendMessage(2125, "{0} gold has been withdrawn from your gold ledger.", totalCost.ToString("#,0"));
                            bought = true;
                            fromLedger = true;
                        }
                    }
					else if (buyer.BankBox.ConsumeTotal(typeof(Gold), totalCost))
					{
						if (Core.Debug) buyer.SendMessage(2125, "{0} gold has been withdrawn from your bank.", totalCost.ToString("#,0"));
						bought = true;
						fromLedger = false;
					}
                }

Adding an additional Else didn't help as far as if all of the above wouldn't work. *throws hands in the air*
 
Last edited:
not sure if this will solve your problem, but i did a little rewriting.
without knowing what item3 is, i assumed that goldint was always equal to 0.
i created a loop to go through each item in the player's backpack and if it's gold, add the amount to goldint and then carry on with the rest of the script.


C#:
if (buyer.Backpack != null)
                {
                    Item findledger = buyer.Backpack.FindItemByType(typeof(GoldLedger));
                    GoldLedger ledger = findledger as GoldLedger;
                    //Item item = buyer.Backpack.FindItemByType(typeof(GoldLedger));
                    //GoldLedger ledger = item as GoldLedger;
                   // Item[] item2 = buyer.Backpack.FindItemsByType(typeof(Gold));
                    int goldint = 0;
                   
                    //foreach (Item item3 in item2)
                      //  goldint += item3.Amount;
                     
                    // checks to see if there's anything in their backpack
                    if (buyer.Backpack.Items.Count > 0) {
                        var ItemsInBackpack = new List<Item>(buyer.Backpack.Items);
                               
                        // goes through each item and if it's gold, it will add the amount to goldint
                        foreach (Item item in ItemsInBackpack) {
                            if ( item is Gold ) {   
                                goldint += item.Amount;
                            }
                        }
                    }
                   
                    //now we have to total amount of the gold in their backpack
                    if (buyer.Backpack.ConsumeTotal(typeof(Gold), totalCost))
                    {
                        if (Core.Debug) buyer.SendMessage(2125, "{0} gold has been withdrawn from your backpack.", totalCost.ToString("#,0"));
                        bought = true;
                    }
                    else if (ledger != null && ledger.Gold != 0)
                    {
                        if (goldint > 0 && (goldint + ledger.Gold) >= totalCost)
                        {
                            buyer.Backpack.ConsumeTotal(typeof(Gold), goldint);
                            if (Core.Debug) buyer.SendMessage(2125, "{0} gold was taken from your backpack.", goldint.ToString("#,0"));
                            ledger.Gold -= (totalCost - goldint);
                            if (Core.Debug) buyer.SendMessage(2125, "The balance of {0} gold was withdrawn from your gold ledger.", (totalCost - goldint).ToString("#,0"));
                            bought = true;
                            fromLedger = true;
                        }
                        else if (ledger.Gold >= totalCost)
                        {
                            ledger.Gold -= totalCost;
                            if (Core.Debug) buyer.SendMessage(2125, "{0} gold has been withdrawn from your gold ledger.", totalCost.ToString("#,0"));
                            bought = true;
                            fromLedger = true;
                        }
                    }
                    else if (buyer.BankBox.ConsumeTotal(typeof(Gold), totalCost))
                    {
                        if (Core.Debug) buyer.SendMessage(2125, "{0} gold has been withdrawn from your bank.", totalCost.ToString("#,0"));
                        bought = true;
                        fromLedger = false;
                    }
                }
 
@zerodowned SO close dude!!! Here's what worked without issue:
Example 1: Player has loose gold in their backpack with no Ledger. (total cost is taken from the loose gold.)
Example 2. Player has loose gold in their backpack with an empty Ledger. (total cost is taken from the loose gold.)
Example 3. Player has NO loose gold, but gold in their Ledger. (total cost is taken from the Ledger.)
Example 4. Player has NO loose gold with an empty Ledger, but loose gold in their bankbox. (total cost is taken from their bank box.)

Here's what did not work:
Example 5. Player has NO loose gold in their backpack, and empty Ledger and NO loose gold in their bank, BUT has bank checks.
This causes the buy gump to just hang there (with no indication that the player does not have the gold to make the purchase.

Originally, gold would be taken from a check if the check was large enough to cover the purchase price, but that's not happening anymore either.
 
hmm, well the only way i think to handle that is to go through each check in their bank, get the total value of them, delete each check and then make a new one with the value minus the purchase amount.

that's a bit messy but it would work

i feel like the auction system has something that will draw funds from checks in you bankbox. let me check that
 
here it is from xanthos auction system


Code:
public static int GetBalance( Mobile from, out Item[] gold, out Item[] checks )
        {
            int balance = 0;

            Container bank = from.BankBox;

            if ( bank != null )
            {
                gold = bank.FindItemsByType( typeof( Gold ) );
                checks = bank.FindItemsByType( typeof( BankCheck ) );

                for ( int i = 0; i < gold.Length; ++i )
                    balance += gold[i].Amount;

                for ( int i = 0; i < checks.Length; ++i )
                    balance += ((BankCheck)checks[i]).Worth;
            }
            else
            {
                gold = checks = new Item[0];
            }

            return balance;
        }

        public static bool Withdraw( Mobile from, int amount )
        {
            Item[] gold, checks;
            int balance = GetBalance( from, out gold, out checks );

            if ( balance < amount && Arya.Savings.SavingsAccount.BalanceGold( from ) < amount - balance )
                return false;

            for ( int i = 0; amount > 0 && i < gold.Length; ++i )
            {
                if ( gold[i].Amount <= amount )
                {
                    amount -= gold[i].Amount;
                    gold[i].Delete();
                }
                else
                {
                    gold[i].Amount -= amount;
                    amount = 0;
                }
            }

            for ( int i = 0; amount > 0 && i < checks.Length; ++i )
            {
                BankCheck check = (BankCheck)checks[i];

                if ( check.Worth <= amount )
                {
                    amount -= check.Worth;
                    check.Delete();
                }
                else
                {
                    check.Worth -= amount;
                    amount = 0;
                }
            }

            if ( amount > 0 )
                Arya.Savings.SavingsAccount.WithdrawGold( from, amount );

            return true;
        }
 
That might be a viable solution, but prior to the edits for the Gold Ledger, the total cost was subtracted from any one check with a value larger than the total cost. Which is what should still be happening, but for whatever reason, when the If/Else If statements all return false, it's not moving on to the next function and that's the bank check withdrawal. I tried adding a return; at the very end, but that won't even compile.

Also, with Xanthos Auction System, the core I'm running (when it was upgraded to use the latest ultima.dll) broke the system. So the references won't even work properly because things were left out of the current ultima.dll that were in one of the older versions.
 
hmm...well I thinking about maybe going through each check and finding the total of all combined and if that's larger than the buy amount it then moves through each check, deducts the amount from it and if that check is then 0 it deletes it.

that's what Xanthos' ( Xanthos's ?? ) code is doing.

i'll give it a shot either tonight or over the weekend.
 
Here's what I did earlier today:

1. Unpacked the original (totally unedited) BaseVendor.cs.
2. Installed it and zipped my modified BaseVendor.cs (this broke a few systems obviously, but restored Buy/Sell to OSI functionality).
3. Removed loose gold from my backpack and bankbox, leaving only a check for 5,000 gold in my bankbox.
4. Purchased one Greater Healing potion from a vendor (100gp).
5. Checked the check in my bank, new balance: 4,900 gold.

So that's original OSI functionality to remove the gold from a bank check if no other loose gold is available. I think the actual Gold in the bankbox needs a variable assignment, because item3 it seems is the balance of backpack loose gold + Ledger balance. Yeah, I think it's going to be that simple, let me give it a try...
 
strange the only part i see about taking funds from the bank only mentions gold, not bankchecks

thanks though
 
Yeah, I noticed that too. Perhaps there is a function of the bankbox hidden in another script somewhere. Alas there isn't an actual bankbox script though and Playermobile just deals with items being deposited into a player's bank. *throws hands in the air*

I've fixed some very odd problems over the years, seemingly more complicated than this, and I can't believe I'm stuck here.
 
The fixes on this are awesome, finally gold is not removed twice using the ledger and their bank!! If the whole check problem can't be solved they can be warned to have gold in their bank :) if none in their ledger-which most always have gold in their ledger.
 
The fixes on this are awesome, finally gold is not removed twice using the ledger and their bank!! If the whole check problem can't be solved they can be warned to have gold in their bank :) if none in their ledger-which most always have gold in their ledger.
Yeah, as a fall back that's what I'd say. I only ran into this because a player bought a brand new Ledger (had not put any gold in it) and immediately went to buy supplies from an NPC vendor heh
 
I'm under the impression that bank checks are obsolete in High Seas meaning that the bank tellers no longer write them and when you drop one in your bank, it gets auto added to the invisible OSI ledger.

My coding is not very good and I've been struggling with getting the gold ledger script to compile without errors. Mind sharing more details on how to implement this resource?

original post looking for help
 

Active Shards

Donations

Total amount
$0.00
Goal
$1,000.00
Back