PERSONALISING A QUEST USING THE NAME_TO_RANDOM() MACRO
======================================================

INTRODUCTION
============

This document gives a brief explanation of how to use the NAME_TO_RANDOM()
macro to personalise a quest for players. This may help in reducing the way
people can cheat on it. If there are any questions about the contents of
this document, please contact me.

Mercade

NAME_TO_RANDOM(string name, int seed, int range)
================================================

The macro NAME_TO_RANDOM() is defined in the include file <math.h> and it
can be used to generate a "random" number in a particular range based on the
name of a player. For the same seed, the same name will always yield the same
random number. This can be done to personalise quests, making people see a
different status (i.e. colour or shape) somewhere, though each person always
sees the same status. Since this value can be computed every time you need
it, there is no reason to store it somewhere along with the player. Naturally
there is a manual file on the macro, explaining the arguments.

For each situation where you want to use the NAME_TO_RANDOM macro, you have
to come up with a unique seed for that situation. If you want to use a second
situation, then you must use a second seed. Suppose you want to randomise both
the shape of an object and its colour, you must use two seeds. (When using a
different range, the seed might be the same, but it will be nicer to use a
unique one). The seed must ideally be a prime number of 5 of 6 digits, though
this is not truely necessary. However, it is advised to use an odd number that
does not devide by any value in the range you want to use. An example of a
seed is 77237. This number does not devide by anything below 100. Maybe it
even is a prime. I did not check.

EXAMPLE
=======

Let's assume that we want to make a simple quest where we want a player to
fetch a birthday present for someone who does not have time to go shopping
himself. We have a shop that sells all different kinds of coffee mugs and we
want the player to go buy the proper mug. Now, to make it a little more
difficult, we do not sell just one type of coffee mug, but we sell it in 
three types (mug, cup&saucer and glass) and five colours (black, red, blue,
white and green).

In the code where the quest is given out to the player, you could have code
like the following.

/*
 * For both the shape and the colour, we define the seed, the range and an
 * array with the values. Note that the range must be exactly the same as
 * the size of the array of values.
 */
#define SHAPE_SEED  77237
#define SHAPE_RANGE 3
#define SHAPES      ({ "mug", "cup&saucer", "glass" })

#define COLOUR_SEED  563987
#define COLOUR_RANGE 5
#define COLOURS      ({ "black", "red", "blue", "white", "green" })

/*
 * Function name: tell_player_about_quest
 * Description  : This function will tell the player what kind of coffee mug
 *                to fetch. If can be called from an ask-function, or
 *                whatever. This code only gives an example of how to operate
 *                the NAME_TO_RANDOM() macro.
 * Arguments    : object player - the player to do the quest.
 */
void
tell_player_about_quest(object player)
{
    int shape;
    int colour;
    string name;

    /* Get the name of the player. */
    name = player->query_real_name();

    /* Compute the "random" values. for the name of the player and the
     * seed and range for the shape and the colour.
     */
    shape = NAME_TO_RANDOM(name, SHAPE_SEED, SHAPE_RANGE);
    colour = NAME_TO_RANDOM(name, COLOUR_SEED, COLOUR_RANGE);

    /* Give the player the message, using the defined names in the two
     * macros. For me, "mercade", it would yield a "black glass" whereas for
     * "rastlin" it would be a "green cup&saucer"
     */
    tell_object(player, "The lazy woman says: Please bring me a " +
	COLOURS[colour] + " " + SHAPES[shape] +
	" and I shall reward you for it.\");
}

Then later, in the code where you test before you give the experience, you
can use that same NAME_TO_RANDOM(name, SHAPE_SEED, SHAPE_RANGE) call to get
that shape value for a person again, and compare it to the shape of the item
that the player brought back to the questmaster.

