How to- mpcalcs
The mobcommand mpcalc is very useful in recording a mob's status when used on a mob, and can be used to track a player's progress per login session or until they delete.
One of the most confusing things about mpcalcs is the syntax that they follow. I will attempt to explain mpcalcs in as much detail as possible and attempt to break up the syntax, so non-geeks can understand it.
When you want to set a mpcalc, you use the mpcalc command. I will use the following notation throughout many of my guides: <> indicates that the argument is required, [] indicates that the argument is optional, # refers to a number being inserted.
To set mpcalcs, we use the mpcalc command, syntax:
mpcalc [+/-]
target - can be $* or the name of a player/mob in the room
keyword - a string that refers to the name of the mpcalc, for each keyword, there are 32 bits, numbered 0-31 that can be set on/off.
start bit - this number indicates where to start setting the bit. Bits are numbered from right to left starting at 0.
bit length - this shows how many bits, including the starting one, to set (always >=1)
value - this shows what to set the value of the bits to
- or + - these indicate to subtract or add the value to the current value of the bits
The ifcheck for mpcalcs is:
if mpcalc( )
Where the arguments are the same as before and operator is one of the valid operators.
In order to understand mpcalcs, bits will need to be explained. A bit is a value in the binary number system, which is a way of counting numbers similar to the decimal system you are used to but is based on the number 2 instead of the number 10. Where decimal uses the numbers 0-9 to represent a value, binary can only use 0 or 1, thus making binary numbers considerably large than decimal numbers in most cases. Each bit of a binary number represents whether or not a certain power of 2 is present. For example, take the number 122(in base 10) that number is made up of 1*100 (10^2) + 2*10 (10^1) + 2*1 (10^0). In order to convert this number into binary first you must figure out which powers of two would be needed to form this number. The simplest way to do this is to start with the right most digit and divide by two, taking the remainder of each division to be that digit. Thus the first division is 122/2=61 (r0) so there are 0*2^0. The next bit would be determined by 61/2=30 (r1) and therefore give us a 1 in the 2^1 place. Continuing down we get that the number 122(decimal) is 1111010(binary).
The value of the leftmost bit is the same as saying 2^6 (64 in decimal) but that can be extrapolated to fit all cases dependant on the length of the binary number, which gives us that the value of any bit is 2^(n-1) where n is the ordinal number of the bit counting right to left. Using simple mathematics we can determine that the maximum value of any binary number is (2^n)-1 where n is the length of that number. For example, for a binary number of length 3, the highest value would be 111(binary) which converts to 7(decimal) because it's 4+2+1 (each of those bits has a 1 in the place indicated that it is turned 'on'). This is equal to (2^3)-1.
Mpcalcs have 32 bits, however, since the 32nd bit is used to indicate sign the max value of any mpcalc is 2^31-1, leaving the last bit to indicate +/-. From this we can see that the largest value that we can set any given mpcalc to is 2,147,483,647.
Now that I've introduced the math behind mpcalcs, let's see how they actually function. Since each mpcalc keyword contains 32 bits, it can be represented as 00000000000000000000000000000000. For small uses just tracking the status of one event, we usually only need one bit to indicate whether or not the event has occurred. For example, suppose we have 5 holiday items for the Christmas area and we want to track whether or not they've been given. We'd use the command: mpcalc $n xmas2k1 0 1 1 to indicate that the first of five items has been given. This would set the entire string to 00000000000000000000000000000001. Suppose the third item was given now, then we'd use: mpcalc $n xmas2k1 2 1 1. This would set the entire string to 00000000000000000000000000000101 which would show up as 5 when using showquests for the xmas2k1 field, because 00000000000000000000000000000101 is represented as 5 in decimal. Suppose we wanted to test whether or not they were able to obtain all 5 items. Since we're using 5 consecutive bits, we just need to check if mpcalc($n xmas2k1 0 5) == 31 (2^5-1). Likewise we could rapidly reset all the given item flags by doing: mpcalc $n xmask2k1 0 5 0 this would set the bits from 0 (the start bit) to 4 (5 bits away) to the value 0. The starting bit can be anywhere provided that startbit+length-1 < 32 because otherwise we'd be trying to set bits past the amount that it was intended to hold. So in this example, we could easily shift the starting bit to 15 and have it track the items given status with bits 15,16,17,18,19 by using mpcalc $n xmas2k1 15 5.
Now that I've finished discussing the use of mpcalcs as flag toggles representing on/off, let us explore their use as counters. A common misconception when using mpcalcs as counters is that the bitlength must be greater than or equal to the highest number that can be reached by the counter. Since, earlier, I showed how for n bits we could obtain numbers as large as 2^n-1 and not just n. Therefore the highest number one can count to is not n, but(2^n)-1.
Once this misconception has been cleared up, counting using mpcalcs is quite simple. Suppose we want to count the number of times someone has passed through a certain area. We also know that on the 17th pass the prog should transfer them somewhere else. Thus we should keep track of the number of times they've wandered back and forth with a mpcalc. We will need a bitlength of 5 to keep track of the number of times crossing. A bitlength of 5 accommodates numbers up to 31 values, whereas a bitlength of 4 will only accommodate numbers up to 15 (2^n-1 again). Now we just need to increment the counter each time the person crosses. We can do this by using: mpcalc $n xmas2k1 0 5 1 +. Similarly, we can shift the starting bit to allow room for the previous flag toggles. Continuing with our previous example, suppose we used the first 5 bits (mpcalc $n xmas2k1 0 5) for flag indications we can easily shift the starting bit to bit number 5 (remember, only bits 0-4 were used earlier because bit counting starts at the number 0 not at 1), thus making our command: mpcalc xmas2k1 5 5 1 +. To check when they've reached value 17 you just check if mpcalc ($n xmas2k1 5 5) == 17, this will count between bits 5 and 9 to look for a value exactly equal to 17 and the execute whatever commands follow. It is important not to confuse the starting bit number with the bit lenght number. The easiest way to remember is to think of the starting bit number as the power of two that that location takes in the binary number and think of the bit length number as the number of places that binary number takes up.
For even more advanced tracking with mpcalcs you create an mpcalc that will only last until the player quits. In order to do this you must prefix your keyword with an underscore. This tells the mud not to save it to the pfile. For example: mpcalc $n _housinginvite 0 1 0. This will set a temporary mpcalc that will reset itself to 0 each time the player quits because it is not saved to their pfile.
Also, mpcalc keywords CAN be deleted completely from a player's pfile. To do so prefix the !delete! command before mpcalc. So to completely erase the xmas2k1 keyword from a player, the command would be: mpcalc !delete! $n xmas2k1. This will totally erase any permanent mpcalcs of that keyword from a player's pfile.*