This file contains some extra information on the implementation
of the Fanny daemon.

How manages Fanny to walk around in Moist? First, you might have
noticed that Fanny normally has only a limited area in which she can
walk. She won't climb stairs, she won't enter the games room,
she won't enter the caves, etcetera. This is managed by extending
the basic room with four new properties:

modify room
    npc_north = nil
    npc_south = nil
    npc_west = nil
    npc_east = nil
;

Each room now has properties which indicate if an NPC may exit this
room towards the north, east, south and west. Fanny's code takes this
into account.

Fanny's movement is directed by one very large daemon. This daemon is
running all the time. Part of the code for this daemon follows, with
comment in between:

fannymoveDaemon: function( parm )
{
    if  (Fanny.serving <= 0)
        global.servecounter += 1;

In the global object, a "servecounter" is kept. The Fanny actor has a
"serving" property. The serving property indicates wether Fanny is at
the time busy with serving Morghana, that is, with trying to bring
milk to Morghana. As long as the serving property is zero, Fanny can
do whatever she likes; she is not serving. The global servecounter
starts at zero, and every turn, it is increased by 1. As soon as the
servecounter reaches 75, and conditions are favorable, Fanny starts
serving Morghana:

    if  (global.servecounter > 75 and Fanny.serving <= 0 and
        milk.location = nil and Morghana.excitement <= 0 and
        Morghana.orgasms <= 0 and rope.location <> Morghana and
        not( cord.broken ))
    {
        global.servecounter := 0;
        Fanny.serving := 1;
        if  (Fanny.excitement > 0)
            Fanny.excitement := 0;
        if  (Me.location = kitchen)
            "\n\tThe bell in the corner suddenly rings. ";
        else if  (Me.location = bedroom)
            "\n\tMorghana walks over to the cord, and pulls it. You hear
            a bell ring somewhere. ";
        else
            "\n\tYou hear a bell ring somewhere. ";
        if  (Me.location = Fanny.location)
        {
            "Fanny looks up. ";
            if  (rope.location = Fanny)
                "\"Please untie me,\" she says, \"I have to do something.\" ";
            else
                "\"I'm sorry, I have to do something,\" she says. ";
        }
    }

As you can see, conditions are favorable if Fanny is at the time not
busy with serving Morghana, Morghana is not tied up (she can't ring the
bell then), there is milk available, and the bell cord is not broken.
If all is well, the global servecounter is reset to zero, and the Fanny
serving property is set at 1, meaning that Fanny wants to get to the
kitchen now. Her excitement resets to zero, because Morghana takes
precedence over her own horniness.

    else if  (Fanny.serving > 0 and rope.location = Fanny)
    {
        if  (Me.location = Fanny.location)
            "\n\tFanny begs you, \"Please untie me. The queen needs me.\" ";
    }

Now, if Fanny should be serving, but she is tied up, she can't do
anything. Therefore she asks you to release her.

    else if  (rope.location = Fanny)
        return;

OK, if she is not serving, and she is tied up, she can't move and the
daemon ends.

    else if  (Fanny.serving > 0)
    {

So now follows the part in which the who process of getting the milk,
bringing it to Morghana and leaving the milk before Morghana's door
is handled. Fanny's serving counter is increased for each stage in the
process. First she will go to the kitchen, by moving west as far as
she can, the north or south if necessary, and finally into the
kitchen. It starts like this:

        switch (Fanny.serving)
        {
            case 1:
                if  (dildo.location = fanny_ass or
                    dildo.location = fanny_pussy)
                {
                    dildo.moveInto( Fanny.location);
                    if  (Me.location = Fanny.location)
                        "\n\tFanny removes the dildo and drops it. ";
                }
                if  (vibrator.location = fanny_ass or
                    vibrator.location = fanny_pussy)
                {
                    vibrator.moveInto( Fanny.location);
                    if  (Me.location = Fanny.location)
                        "\n\tFanny removes the vibrator and drops it. ";
                }
                if  (Fanny.location.npc_west)
                {
                    if  (Fanny.location = Me.location)
                        "\n\tFanny moves off to the west. ";
                    Fanny.moveInto( Fanny.location.west );
                    if  (Fanny.location = Me.location)
                        "\n\tFanny enters from the east. ";
                }
                else
                    Fanny.serving := 2;
                break;

As you can see, Fanny first removes the dildo and/or vibrator if she
"has" them, and then moves west. If she can't move west any further,
it means she is in the kitchen, the northwest tower or the southwest
corner. In any case, the serving property gets to stage 2.

            case 2:
                if  (Fanny.location = kitchen)
                    Fanny.serving := 3;
                else if  (Fanny.location.npc_north)
                {
                    if  (Fanny.location = Me.location)
                        "\n\tFanny moves off to the north. ";
                    Fanny.moveInto( Fanny.location.north );
                    if  (Fanny.location = Me.location)
                        "\n\tFanny enters from the south. ";
                    Fanny.serving := 1;
                }
                else if  (Fanny.location.npc_south)
                {
                    if  (Fanny.location = Me.location)
                        "\n\tFanny moves off to the south. ";
                    Fanny.moveInto( Fanny.location.south );
                    if  (Fanny.location = Me.location)
                        "\n\tFanny enters from the north. ";
                    Fanny.serving := 1;
                }
                break;

So, what happens here? Either Fanny is in the kitchen, in which case
the serving counter can be increased by 1. Or she must move north
or south, which she does, and then the serving counter is set to 1,
meaning that in next turn, she will go west again, ending up in the
kitchen.

OK, this continues for some time, stage 3 being in the kitchen, stage 4
going east, stage 5 going north, etcetera, etcetera, etcetera. When Fanny
has finished her chores, the serving counter is reset to zero and next
turn, the global servecounter starts to increase again. Incidentely,
if you managed to hinder Fanny in her quest, for instance by drinking
the milk while she is running around with it, the Fanny serving counter
is set back to 1, meaning that she will return to the kitchen and get
new milk.

So lets end this huge case clause, and see what happens if Fanny is not
tied up, and not serving:

    }
    else
    {
        if  ((Fanny.excitement < 0 and Fanny.location = Me.location) or
            (Fanny.excitement < 15 and rand( 9 ) < 3))
        {

First we check if Fanny wants to move. If her excitement is beneath zero,
it means you have done something bad to her and naturally she wants to
get away from you. In that case, she will always try to move. Otherwise,
she wants to move with a chance of 30% if her excitement is below 15.
If her excitement is 15 or higher, something else happens, which follows
later.

            switch (rand(3))
            {

So, if she wants to move, the question is in which direction she tries to
move. Again, a random number decides the direction. Here follows the
code in which Fanny tries to move north:

                case 0:
                    if  (Fanny.location.npc_north)
                    {
                        if  (Fanny.location = Me.location)
                            "\n\tFanny moves off to the north. ";
                        Fanny.moveInto( Fanny.location.north );
                        if  (Fanny.location = Me.location)
                            "\n\tFanny enters from the south. ";
                    }
                    break;

If Fanny wants to move north, and the room allows it, she does. The rest
of the cases is equivalent, and I skip those.

        }
        else if  (Fanny.location <> Me.location and Fanny.excitement >= 15)
        {
            if  (Fanny.location.npc_north and Fanny.location.north = Me.location)
            {
                Fanny.moveInto( Fanny.location.north );
                "\n\tFanny enters from the south with an anxious look on her face. ";
            }
            else if  (Fanny.location.npc_east and
                Fanny.location.east = Me.location)
            {
                Fanny.moveInto( Fanny.location.east );
                "\n\tFanny enters from the west eyeing you with a horny look. ";
            }
            else if  (Fanny.location.npc_south and
                Fanny.location.south = Me.location)
            {
                Fanny.moveInto( Fanny.location.south );
                "\n\tFanny enters from the north, her eyes fastened at your dick. ";
            }
            else if  (Fanny.location.npc_west and
                Fanny.location.west = Me.location)
            {
                Fanny.moveInto( Fanny.location.west );
                "\n\tFanny enters from the east, licking her lips. ";
            }
        }

So, what happens if Fanny's location is 15 or higher? In that case, she
is considered horny and tries to find you. So, if she is not in the same
room as you are, but you are in the next room, she moves to your
position. Otherwise, she just stays put, meaning that if you are in the
same location as Fanny, and she is horny, she won't run away.

    }
}

That's it. It's a lot of code for a daemon, but I think it is the easiest
way of programming a random walking NPC or an NPC with a plan.

