Mathematics

How the Math works in GoldIsMoney

I'm going to try to outline the new math involved in GoldIsMoney as of 1.2. Some of this is so I can get it straight in my mind and some is for your enlightenment.

Each currency is saved in the memory as two TreeHashes (sorted hash), one sorted ascending by worth of the item type and one sorted descending. The built-in families have hardcoded item/worth values based on the normal inventory conversion of the item, e.g. gold nugget = 1, gold ingot = 9, gold block = 81.

Checking your Balance

About

I'm adding a new command (the first and only) to GoldIsMoney so users can check their balance. While in the past, I have said, "Just open your inventory," with the new customizable currencies, this might not be feasible to some setups.

  • /balance - No parameters. Simply states to the player how much money the player entering it has. The text is customizable in config.yml.

Mathematics

A single loop is preformed on the inventory adding to a balance total the worth * item quantity. Pretty simple here.

Withdrawing

About

Withdrawing is the most complex and heavy task that GoldIsMoney has to do. In fact, the deposit functionality is actually included in the withdraw in order to facilitate returning any change due to converting larger denominations. One reason that the process is so heavy is in order to preserve stack locations as much as possible.

When originally in floAuction, all money was taken away and the new total was given. This resulted in an entirely rearranged inventory which the players found very inconvenient and annoying...it was patched in floAuction but never really optimized till in GoldIsMoney. In the second version (as seen in versions 1.0-1.1) of this logic was hardcoded to handle only gold blocks. It used a modulus value to hold how much of each item the player should end up with, but this is impractical in custom currencies because the next denomination may not be a multiple of the previous (e.g. dimes are 10 and quarters are 25). Below is the new method which should satisfy any currency combination.

Mathematics

Main Loop 1

On the first pass, GoldIsMoney loops through the currency definition ascending map (smaller worth items first) and for each item type, loops through the inventory setting each item of that type to the max of zero or whatever is necessary to bring the total worth removed below or equal to the amount needing to be removed.

I.e. It removes items from the inventory as much as necessary, smallest worth items first.

Main Loop 2

This second pass, the first part of giving change from the previous pass, is a loop through the currency definition's descending map (greater worth items first). For each item type, a loop through the inventory is preformed adding the item to any existing stack (including the zero quantity stacks from the previous loop) whatever change can be given in that denomination. This is done in order optimize inventory space while preserving the existing stack locations in the player's inventory.

I.e. It adds the change to any existing inventory stack (or stack removed from the previous loop) as much as it can, higher worth items first.

After this point, any zero quantity item stacks are deleted from the inventory. You see, item stacks can have quantity of zero which does not count as a free inventory space by the system. This is useful as it allows me to set the value to zero while remembering the location of that type of item if we need to give change in that denomination. They have to be removed (set to null, instead of ItemStack) before new items can be put in those locations as the next pass will do.

I.e. The memory of where stacks used to be is cleared.

Main Loop 3

The last pass in the withdraw logic will dispense any remaining change into new stacks. Looping the descending currency definition map (greater worth items first), new stacks are generated for any free inventory slots discovered until either no inventory slots are available or all the change has been given.

I.e. It gives what's left of the change in as many new stacks of items as necessary, higher worth items first.

If there is not enough inventory space, the undispensed items are stored in a variable to be dispensed when a player removes an item from their inventory. This data is saved to the HDD as a serialized array in case a server crash happens so no money is lost. It is only read from that file when GoldIsMoney is initialized.

I.e. If it can't give all the change, it remembers and tries to give it when there's free inventory space.

Depositing

About

Depositing and withdrawing actually are the same process. The depositing activity is the same as the change dispensation of the withdraw process. Parts of the process aren't necessary when depositing, so those are skipped. By the time the withdraw logic is fully hashed out in code, the depositing logic exists.

Mathematics

Main Loop 1

The main loop in the balance changing code is skipped because the difference in the existing balance and new balance is positive, therefore no items need to be removed.

I.e. Nothing happens here.

Main Loop 2

Like in the withdraw's Main Loop 2, the descending currency definition map (higher worth item types first) is looped through, and for each item type, existing stacks in the inventory are filled as much as possible up to whatever needs to be given. There are no zero size stacks because nothing has been removed so the cleanup for that is skipped.

I.e. It adds the deposit as much as it can to existing stacks, higher worth items first.

Main Loop 3

Again, like in the withdraw, the descending currency definition map (higher worth first) is used. Any items are given out as necessary. Any remaining balance above what the inventory can hold is stored the same as described in the withdraw section.

I.e. It adds the deposit in as many new item stacks as it can, higher worth items first. If there's not enough space, it remembers and gives the items when there's space.