/**
 * Making a room clone and set up a basic NPC.
 * October '01 by Avelan
 */
#include "defs.h"
inherit ROOM_OBJ;
/*
 * Here we declare a (global) variable 'butterfly', that is an object.
 *
 * You could also just declare it inside a function, but you would then
 * have to declare it separately in every function you use it in.
 *
 * The main difference between a local variable (that is declared inside
 * a single function only) and a global variable (declared globally in
 * an object, such as this room) is that the value of a global variable
 * is stored and it can be used in every function in the object, whereas
 * a local variable only exists when the specific function is called,
 * and isn't stored in any way.
 *
 * We are using a global variable here, so that we can keep track of the
 * NPC that is cloned - when the NPC is cloned, we will assign the object
 * we created to this variable.  This variable will then be keeping the
 * value of the NPC object, and will be usable in any function of the room.
 */
object butterfly;
/*
 * Here we add a 'prototype' function called make_fly().
 * This is needed because the make_fly() function itself is in the end
 * of the file, while the setup function is trying to use it earlier.
 * Another way would be to move the make_fly code in front of the
 * setup function, that way the prototype wouldn't be needed (but I like
 * having setup as the first function in my rooms :) ).
 */
void make_fly();
void setup() {
    set_zone("npc_school");
    set_determinate("an ");
    set_short("NPC cloning room");
    set_light(100);
    set_long("This room explains how to clone an NPC without having to "
        "write a separate file for it.  This is the preferred way of "
        "creating simple NPCs that have no additional functionality "
        "besides chats.  It is preferable, because this way there won't "
        "be a 'master copy' of the NPC loaded into the memory at any "
        "time, but instead the room (or any object for that matter) sets "
        "up the properties for the NPC.\n"
        "Note - if you 'more' the NPC here, you will see the contents of "
        "the basic NPC object, since it doesn't have its own file.\n");
    add_item("master copy", "What is called a master copy in LPC, is in fact "
        "an object just like any other.  The difference between a clone an a "
        "master copy is subtle, yet important.  When a file is loaded into "
        "the memory by the mud, a master copy is created, which is then used "
        "to make clones from.  There are several ways to make out whether or "
        "not you're dealing with a master copy or a clone - the easiest of "
        "them probably being the 'pathof' command, which will return the "
        "object reference or file name of an object.  Master copies will "
        "always have the exact name of the file they were loaded from, while "
        "clones will have an object number tacked to the end of the file "
        "name.  For example 'pathof me' will give me /global/creator#33391, "
        "which means I have been cloned from an object called "
        "/global/creator, and 'pathof butterfly' will give me "
        "/std/npc#12947, which means the butterfly is a clone of /std/npc, "
        "which is the main NPC inheritable.  Rooms in most cases "
        "('pathof here') are all master copies, because there is really no "
        "need to make a clone of a room, because most rooms look rather "
        "different.");
    add_exit("forward", NPCSCHOOL+"npc_school02", "path");
    add_exit("back", NPCSCHOOL+"start", "path");
    /*
     * Here we make a butterfly right when the room loads.
     * This way the first person to enter and load the room will have
     * a butterfly here instantly, instead of waiting for the call out
     * in reset to execute.
     */
    make_fly();
} /* setup() */
/**
 * The reset function is called on each and every object
 * in the mud periodically by the mud driver.
 * This makes it the preferred way of checking whether
 * or not to clone NPCs.
 */
void reset() {
    /*
     * We could have the NPC made inside the reset()
     * but it's better to do anything crucial inside
     * another function, to 'spread the load', so to speak.
     * This is because reset() is called on a number of
     * objects at the same time, and it would lag the mud
     * considerably if each an every one of them tried to
     * execute some code all at the same time.
     */
    /*
     * This if statement checks whether or not there is already
     * an object assigned to the butterfly variable.
     * The exclamation mark basically means 'no' in LPC -
     * therefore if there is no butterfly, we will make a new one
     * with a call out to a function called make_fly, in 4 seconds.
     */
    if( !butterfly )
        call_out("make_fly", 4 );
} /* reset() */
/**
 * This is the function that will actually clone the NPC.
 */
void make_fly() {
    /*
     * Check once more for the existence of the NPC, just in case :)
     */
    if( !butterfly ) {
        /*
         * Here we clone the basic NPC object and assign the
         * created object to the 'butterfly' variable, and mold
         * it to our needs.  We give it everything we would in
         * a normal NPC file and then move it into the room.
         *
         * NOTE : This is the preferred way of cloning every
         * simple NPC, ie. the kind that don't do anything else
         * than just stand there chatting, waiting to be killed.
         */
        butterfly = clone_object(NPC_OBJ);
        butterfly->set_name("butterfly");
        butterfly->set_short("butterfly");
        butterfly->set_determinate("a ");
        butterfly->set_long("This is a beautiful butterfly fluttering about "
            "with spotted, colourful wings and sad little eyes.  The wings "
            "make an image that looks like the face of some larger "
            "creature.\n");
        butterfly->basic_setup("insect", 1 + random( 5 ), "male");
        butterfly->load_chat( 30, ({
            1, ":flutters about.",
            1, ":flutters closer to you.",
            1, ":lands to rest on a nearby flower.",
            1, ":makes no noise at all."
            }));
        butterfly->load_a_chat( 60, ({
            1, ":makes an effort to fly as far as possibly from you.",
            1, ":looks dazed.",
            1, ":flutters its wings threateningly."
            }));
        butterfly->move( TO, "$N flutter$s in from somewhere.");
    }
} /* make_fly() */