Chapter 16

Mathematics

Have you ever wondered why mathematicians look at you strangely? Somewhere in the digits of pi, your diary is written in plain ASCII.

The basic mathematical operators were already described in section 6.10. Many additional mathematical functions are provided for various specialized purposes. These are described in the following sections.

1. Randomness

Chance plays a large role in many types of games, so DM provides several instructions that make use of randomness. In actual fact, they all rely on a pseudo-random number generator which only appears to be random. However, for all practical purposes, they can be relied upon to provide probabilistic results with no discernible pattern.

1.1 rand

The rand instruction generates a random number in the specified range. The number returned is always an integer, so to get fractional numbers, you would need to specify some larger range and then divide the result.

rand (L=0,U)
L is the lower bound.
U is the upper bound.
Returns a number equal to or between L and U.

If only a single argument is given, it is treated as the upper bound and the lower bound takes its default of zero.

The following example makes a potion for gamblers.

obj/potion/lucky
   verb/drink()
      usr.AddLife(rand(-20,20))

Depending on how lucky the user is, the potion could do anything from -20 in damage to +20 in healing.

This code assumes the definition of an AddLife() procedure that handles healing or damaging a mob. It would be similar to the HurtMe() proc defined in section 6.1 but with the meaning of the argument reversed.

1.2 prob

The prob instruction is true or false with a probability specified in the form of a percentage.

prob (P)
P is the percent chance of being true.
Returns 1 P percent of the time, otherwise 0.

This can be used to choose between one of two possible outcomes. The following example gives a player a certain chance of bad side-effects when drinking a magic potion.

obj/potion/health
   verb/drink()
      if(prob(20)) //backfire 20% of time
         usr.AddLife(-10)
      else
         usr.AddLife(20)

1.3 roll

The roll instruction rolls some dice for you and returns the sum obtained. The sides of the dice are numbered from one to the number of sides and all are equally likely.

roll (dice=1,sides)
roll ("dicedsides")
dice is the number of dice to roll.
sides is the number of sides on the dice.
Returns the sum of the dice.

The dice parameters can either be specified as two separate numerical arguments or as one combined text value. The text version might be useful if you want to store the dice parameters in a single variable.

The following example uses roll to compute the impact of a weapon.

obj/weapon
   var/power
   clipboard
      power = "1d4"
   calculator
      power = "2d6"

   verb/swing(mob/trg in view(1))
      var/damage = roll(power)
      view() << "[usr] hits [trg] with \a [src] for [damage] point\s!"

In both programming and combat, you have to make do with what you have.

1.4 pick

The pick instruction randomly chooses one of its arguments and returns that value.

pick (Val1,Val2,...)
Returns one of the given values.

If you want to give a particular value a higher or lower chance of being chosen, a relative probability may be specified. A relative probability of 200 is twice as likely as the norm, 50 is half, and so on.

prob (P); Val
Or P; Val
P is relative probability (default is 100).
Val is the value with the altered likelihood.

The following example uses pick() to implement a fortune cookie.

obj/fortune_cookie
   verb/eat()
      usr << "The message inside says:"
      usr << pick (
         "Never trust an undead doctor.",
         "Only trust undead lawyers.",
        prob(25)
         "The throne marks the way.",
        prob(10)
         "The wall behind the throne is an illusion!"
      )
      del(src)

In this example, there are a couple messages with the normal default probability, one a quarter as likely, and one a tenth as likely to be seen. Note how prob() may be followed by a newline instead of a semicolon since the two are equivalent. That allows you to line things up, if you are the lining-up sort of person.

2. abs

The abs instruction computes the absolute value of a number.

abs (N)
N is a numerical expression.
Returns the absolute value.

3. min

The min instruction returns the minimum of its arguments.

min (N1,N2,...)
N1 is the first numerical expression.
N2 is the second and so on.
Returns the minimum value.

4. max

The max instruction returns the maximum of its arguments.

max (N1,N2,...)
N1 is the first numerical expression.
N2 is the second and so on.
Returns the maximum value.

5. round

The round instruction rounds a number to the nearest specified multiple. If no rounding multiple is specified (or if it is zero), the integer portion is returned. Note that this is different from specifying a multiple of 1, which rounds to the nearest integer.

round (N,M)
N is the numerical expression to round.
M is the rounding multiple.
Returns the nearest multiple of M to N.

6. sqrt

The sqrt instruction computes the square root of a number. This is equivalent to raising the number to the power of 1/2 using the ** operator but is provided for convenience.

sqrt (N)
N is a numerical expression.
Returns the square root.