skylib_fluffos_v3/
skylib_fluffos_v3/bin/
skylib_fluffos_v3/bin/db/
skylib_fluffos_v3/fluffos-2.9-ds2.04/
skylib_fluffos_v3/fluffos-2.9-ds2.04/ChangeLog.old/
skylib_fluffos_v3/fluffos-2.9-ds2.04/Win32/
skylib_fluffos_v3/fluffos-2.9-ds2.04/compat/
skylib_fluffos_v3/fluffos-2.9-ds2.04/compat/simuls/
skylib_fluffos_v3/fluffos-2.9-ds2.04/include/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/clone/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/command/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/data/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/etc/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/include/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/inherit/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/inherit/master/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/log/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/compiler/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/efuns/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/operators/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/u/
skylib_fluffos_v3/fluffos-2.9-ds2.04/tmp/
skylib_fluffos_v3/fluffos-2.9-ds2.04/windows/
skylib_fluffos_v3/mudlib/
skylib_fluffos_v3/mudlib/cmds/
skylib_fluffos_v3/mudlib/cmds/admin/
skylib_fluffos_v3/mudlib/cmds/guild-race/
skylib_fluffos_v3/mudlib/cmds/living/broken/
skylib_fluffos_v3/mudlib/cmds/player/group_cmds/
skylib_fluffos_v3/mudlib/cmds/playtester/
skylib_fluffos_v3/mudlib/d/admin/
skylib_fluffos_v3/mudlib/d/admin/room/
skylib_fluffos_v3/mudlib/d/admin/room/we_care/
skylib_fluffos_v3/mudlib/d/admin/save/
skylib_fluffos_v3/mudlib/d/admin/text/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/buildings/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/map/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/roads/
skylib_fluffos_v3/mudlib/d/learning/chars/
skylib_fluffos_v3/mudlib/d/learning/functions/
skylib_fluffos_v3/mudlib/d/learning/handlers/
skylib_fluffos_v3/mudlib/d/learning/help_topics/
skylib_fluffos_v3/mudlib/d/learning/help_topics/npcs/
skylib_fluffos_v3/mudlib/d/learning/help_topics/objects/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rcs_demo/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rcs_demo/RCS/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/crowd/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/situations/
skylib_fluffos_v3/mudlib/d/learning/save/
skylib_fluffos_v3/mudlib/d/learning/school/
skylib_fluffos_v3/mudlib/d/learning/school/add_sc/
skylib_fluffos_v3/mudlib/d/learning/school/characters/
skylib_fluffos_v3/mudlib/d/learning/school/general/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/basic_commands/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/edtutor/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/unix_tutor/
skylib_fluffos_v3/mudlib/d/learning/school/items/
skylib_fluffos_v3/mudlib/d/learning/school/npc_school/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/room_basic/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/situations/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/terrain_tutor/
skylib_fluffos_v3/mudlib/d/learning/text/
skylib_fluffos_v3/mudlib/d/liaison/
skylib_fluffos_v3/mudlib/d/mudlib/
skylib_fluffos_v3/mudlib/d/mudlib/changes/
skylib_fluffos_v3/mudlib/d/playtesters/
skylib_fluffos_v3/mudlib/d/playtesters/effects/
skylib_fluffos_v3/mudlib/d/playtesters/handlers/
skylib_fluffos_v3/mudlib/d/playtesters/items/
skylib_fluffos_v3/mudlib/d/sage/
skylib_fluffos_v3/mudlib/doc/
skylib_fluffos_v3/mudlib/doc/creator/
skylib_fluffos_v3/mudlib/doc/driver/
skylib_fluffos_v3/mudlib/doc/driver/efuns/arrays/
skylib_fluffos_v3/mudlib/doc/driver/efuns/buffers/
skylib_fluffos_v3/mudlib/doc/driver/efuns/calls/
skylib_fluffos_v3/mudlib/doc/driver/efuns/compile/
skylib_fluffos_v3/mudlib/doc/driver/efuns/filesystem/
skylib_fluffos_v3/mudlib/doc/driver/efuns/floats/
skylib_fluffos_v3/mudlib/doc/driver/efuns/functions/
skylib_fluffos_v3/mudlib/doc/driver/efuns/general/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mappings/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mixed/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mudlib/
skylib_fluffos_v3/mudlib/doc/driver/efuns/numbers/
skylib_fluffos_v3/mudlib/doc/driver/efuns/parsing/
skylib_fluffos_v3/mudlib/doc/login/
skylib_fluffos_v3/mudlib/doc/lpc/basic_manual/
skylib_fluffos_v3/mudlib/doc/lpc/intermediate/
skylib_fluffos_v3/mudlib/doc/new/add_command/
skylib_fluffos_v3/mudlib/doc/new/events/
skylib_fluffos_v3/mudlib/doc/new/handlers/
skylib_fluffos_v3/mudlib/doc/new/living/race/
skylib_fluffos_v3/mudlib/doc/new/living/spells/
skylib_fluffos_v3/mudlib/doc/new/object/
skylib_fluffos_v3/mudlib/doc/new/player/
skylib_fluffos_v3/mudlib/doc/new/room/guild/
skylib_fluffos_v3/mudlib/doc/new/room/outside/
skylib_fluffos_v3/mudlib/doc/new/room/storeroom/
skylib_fluffos_v3/mudlib/doc/object/
skylib_fluffos_v3/mudlib/doc/playtesters/
skylib_fluffos_v3/mudlib/doc/policy/
skylib_fluffos_v3/mudlib/doc/weapons/
skylib_fluffos_v3/mudlib/global/
skylib_fluffos_v3/mudlib/global/creator/
skylib_fluffos_v3/mudlib/handlers/
skylib_fluffos_v3/mudlib/include/casino/
skylib_fluffos_v3/mudlib/include/cmds/
skylib_fluffos_v3/mudlib/include/effects/
skylib_fluffos_v3/mudlib/include/npc/
skylib_fluffos_v3/mudlib/include/room/
skylib_fluffos_v3/mudlib/include/shops/
skylib_fluffos_v3/mudlib/net/daemon/
skylib_fluffos_v3/mudlib/net/daemon/chars/
skylib_fluffos_v3/mudlib/net/inherit/
skylib_fluffos_v3/mudlib/net/obj/
skylib_fluffos_v3/mudlib/net/obj/BACKUPS/
skylib_fluffos_v3/mudlib/obj/amulets/
skylib_fluffos_v3/mudlib/obj/armours/plate/
skylib_fluffos_v3/mudlib/obj/b_day/
skylib_fluffos_v3/mudlib/obj/clothes/transport/horse/
skylib_fluffos_v3/mudlib/obj/faith/symbols/
skylib_fluffos_v3/mudlib/obj/fungi/
skylib_fluffos_v3/mudlib/obj/gatherables/
skylib_fluffos_v3/mudlib/obj/instruments/
skylib_fluffos_v3/mudlib/obj/media/
skylib_fluffos_v3/mudlib/obj/misc/player_shop/
skylib_fluffos_v3/mudlib/obj/monster/godmother/
skylib_fluffos_v3/mudlib/obj/monster/transport/
skylib_fluffos_v3/mudlib/obj/rings/
skylib_fluffos_v3/mudlib/obj/scabbards/
skylib_fluffos_v3/mudlib/obj/spells/
skylib_fluffos_v3/mudlib/obj/stationery/
skylib_fluffos_v3/mudlib/obj/stationery/envelopes/
skylib_fluffos_v3/mudlib/obj/toys/
skylib_fluffos_v3/mudlib/obj/vessels/
skylib_fluffos_v3/mudlib/obj/weapons/axes/
skylib_fluffos_v3/mudlib/obj/weapons/chains/
skylib_fluffos_v3/mudlib/obj/weapons/maces/BACKUPS/
skylib_fluffos_v3/mudlib/save/autodoc/
skylib_fluffos_v3/mudlib/save/book_handler/
skylib_fluffos_v3/mudlib/save/books/history/calarien/
skylib_fluffos_v3/mudlib/save/mail/
skylib_fluffos_v3/mudlib/save/new_soul/data/
skylib_fluffos_v3/mudlib/save/parcels/
skylib_fluffos_v3/mudlib/save/playerinfo/
skylib_fluffos_v3/mudlib/save/players/d/
skylib_fluffos_v3/mudlib/save/players/s/
skylib_fluffos_v3/mudlib/save/random_names/
skylib_fluffos_v3/mudlib/save/random_names/data/
skylib_fluffos_v3/mudlib/save/terrains/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_desert/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_grassy_field/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_mountain/
skylib_fluffos_v3/mudlib/save/todo_lists/
skylib_fluffos_v3/mudlib/secure/
skylib_fluffos_v3/mudlib/secure/cmds/admin/
skylib_fluffos_v3/mudlib/secure/cmds/lord/
skylib_fluffos_v3/mudlib/secure/config/
skylib_fluffos_v3/mudlib/secure/handlers/autodoc/
skylib_fluffos_v3/mudlib/secure/handlers/intermud/
skylib_fluffos_v3/mudlib/secure/include/global/
skylib_fluffos_v3/mudlib/secure/save/
skylib_fluffos_v3/mudlib/secure/save/handlers/
skylib_fluffos_v3/mudlib/secure/std/
skylib_fluffos_v3/mudlib/secure/std/classes/
skylib_fluffos_v3/mudlib/secure/std/modules/
skylib_fluffos_v3/mudlib/std/creator/
skylib_fluffos_v3/mudlib/std/dom/
skylib_fluffos_v3/mudlib/std/effects/
skylib_fluffos_v3/mudlib/std/effects/external/
skylib_fluffos_v3/mudlib/std/effects/fighting/
skylib_fluffos_v3/mudlib/std/effects/magic/
skylib_fluffos_v3/mudlib/std/effects/magic/BACKUPS/
skylib_fluffos_v3/mudlib/std/effects/other/BACKUPS/
skylib_fluffos_v3/mudlib/std/effects/priest/
skylib_fluffos_v3/mudlib/std/effects/room/
skylib_fluffos_v3/mudlib/std/environ/
skylib_fluffos_v3/mudlib/std/guilds/
skylib_fluffos_v3/mudlib/std/guilds/old/
skylib_fluffos_v3/mudlib/std/languages/
skylib_fluffos_v3/mudlib/std/liquids/
skylib_fluffos_v3/mudlib/std/npc/
skylib_fluffos_v3/mudlib/std/npc/goals/
skylib_fluffos_v3/mudlib/std/npc/goals/basic/
skylib_fluffos_v3/mudlib/std/npc/goals/misc/
skylib_fluffos_v3/mudlib/std/npc/plans/
skylib_fluffos_v3/mudlib/std/npc/plans/basic/
skylib_fluffos_v3/mudlib/std/npc/types/
skylib_fluffos_v3/mudlib/std/npc/types/helper/
skylib_fluffos_v3/mudlib/std/npcs/
skylib_fluffos_v3/mudlib/std/outsides/
skylib_fluffos_v3/mudlib/std/races/shadows/
skylib_fluffos_v3/mudlib/std/room/basic/BACKUPS/
skylib_fluffos_v3/mudlib/std/room/basic/topography/
skylib_fluffos_v3/mudlib/std/room/controller/
skylib_fluffos_v3/mudlib/std/room/inherit/topography/
skylib_fluffos_v3/mudlib/std/room/topography/area/
skylib_fluffos_v3/mudlib/std/room/topography/iroom/
skylib_fluffos_v3/mudlib/std/room/topography/milestone/
skylib_fluffos_v3/mudlib/std/shadows/curses/
skylib_fluffos_v3/mudlib/std/shadows/disease/
skylib_fluffos_v3/mudlib/std/shadows/fighting/
skylib_fluffos_v3/mudlib/std/shadows/healing/
skylib_fluffos_v3/mudlib/std/shadows/magic/
skylib_fluffos_v3/mudlib/std/shadows/poison/
skylib_fluffos_v3/mudlib/std/shadows/room/
skylib_fluffos_v3/mudlib/std/shops/controllers/
skylib_fluffos_v3/mudlib/std/shops/objs/
skylib_fluffos_v3/mudlib/std/shops/player_shop/
skylib_fluffos_v3/mudlib/std/socket/
skylib_fluffos_v3/mudlib/std/soul/d/
skylib_fluffos_v3/mudlib/std/soul/e/
skylib_fluffos_v3/mudlib/std/soul/i/
skylib_fluffos_v3/mudlib/std/soul/j/
skylib_fluffos_v3/mudlib/std/soul/k/
skylib_fluffos_v3/mudlib/std/soul/l/
skylib_fluffos_v3/mudlib/std/soul/n/
skylib_fluffos_v3/mudlib/std/soul/o/
skylib_fluffos_v3/mudlib/std/soul/q/
skylib_fluffos_v3/mudlib/std/soul/r/
skylib_fluffos_v3/mudlib/std/soul/u/
skylib_fluffos_v3/mudlib/std/soul/v/
skylib_fluffos_v3/mudlib/std/soul/y/
skylib_fluffos_v3/mudlib/std/soul/z/
skylib_fluffos_v3/mudlib/std/stationery/
skylib_fluffos_v3/mudlib/w/
skylib_fluffos_v3/mudlib/w/default/
skylib_fluffos_v3/mudlib/w/default/armour/
skylib_fluffos_v3/mudlib/w/default/clothes/
skylib_fluffos_v3/mudlib/w/default/item/
skylib_fluffos_v3/mudlib/w/default/npc/
skylib_fluffos_v3/mudlib/w/default/room/
skylib_fluffos_v3/mudlib/w/default/weapon/
skylib_fluffos_v3/mudlib/www/
skylib_fluffos_v3/mudlib/www/java/
skylib_fluffos_v3/mudlib/www/secure/
skylib_fluffos_v3/mudlib/www/secure/lpc/advanced/
skylib_fluffos_v3/mudlib/www/secure/lpc/intermediate/
skylib_fluffos_v3/win32/
/**
 * The library is a sort of information center.
 * Currently it supports only the recording on stories about players and
 * recording the quests that they have done.
 * @author Furball
 * @see /include/library.h
 */

#include <quest_handler.h>

#define SHARED 10
#define UNSHARED 90
#define RESTORE_PATH  "save/library/"

inherit "/std/object";

int *times;
string player_name, *quests, text_file;
mapping player_quest_info;

nosave mapping qps;

int new_top_quest();

/** @ignore yes */
private void init_data(string pl_name) {
    player_name = pl_name;
    quests = ({ });
    times = ({ });
    text_file = "";
    player_quest_info = ([ ]);
} /* init_data() */

/** @ignore yes */
private int get_data_file( string name ) {
    int success;

    if( player_name != name ) {
        success = unguarded( (: restore_object, RESTORE_PATH+name[0..0]+"/"+name :) );
        if( !success ) {
            init_data( name );
        }
        return success;
    }
    return 1;
} /* get_data_file() */

/** @ignore yes */
private void save_data_file( string name ) {
    unguarded( (: save_object, RESTORE_PATH+name[0..0]+"/"+name :) );
    return ;
} /* save_data_file() */

/**
 * This method returns the players current title.
 * @param name the name of the player
 * @return their current title, 0 if no title
 * @see /handlers/quest_handler.c
 */
string query_title( string name ) {
    get_data_file( name );
    if( !quests || !sizeof( quests ) )
        return 0;
    return (string)QUEST_HANDLER->query_quest_title( choice( quests ) );
} /* query_title() */

/**
 * This method returns the set of currently completed quests by the
 * player.
 * @param name the name of the player
 * @return the array of completed quests
 */
string *query_quests( string name ) {
    get_data_file(name);
    if( !quests )
        return ({ });
    return quests + ({ });
} /* query_quests() */

/**
 * This method returns the most recently completed quest by the player.
 * @param name the player name
 * @return the most recently completed quest
 */
string get_most_recent_quest( string name ) {
    int loop, highest;
    string quest_name;

    if( !get_data_file(name) )
        return "Sorry";

    if( !sizeof(quests) )
        return "None";

    for( highest = loop = 0; loop < sizeof(quests); loop++ ) {
        if( times[loop] > highest ) {
            highest = times[loop];
            quest_name = quests[loop];
        }
    }

    return quest_name;

} /* get_most_recent_quest() */

/**
 * This method gets the most recent time a quest was complete by the
 * player.
 * @param name the name of the player
 * @return the time of the most recently completed quest
 */
int get_most_recent_time( string name ) {
    int *t;

    if( !get_data_file(name) )
        return -1;

    if( !sizeof(quests) )
        return 0;

    if( !sizeof( t = sort_array( times, -1 ) ) )
        return 0;


    return t[0];

} /* get_most_recent_time() */

/**
 * This method sets the player as having done the quest and if we
 * should give them xp for it
 * This function should be called when a quest is finished.  It will then
 * call the quest_completed function on the quest handler and do all
 * assorted modifications to the player object etc.  The name should be the
 * players name and the quest should be the name of the quest that is
 * stored in the quest handler.
 * <p>
 * The include file <library.h> should be used for calls to this
 * handler.
 * @return 0 if the quest is already completed
 * @see /handlers/quest_handler->quest_completed()
 * @param pl_name name of the player
 * @param qu_name name of the quest
 * @param no_xp do not give out xp
 * @example
 * // Set the player as completing the womble friend quest, they get
 * // xp for it.
 * LIBRARAY->set_quest(this_player()->query_name(), "womble friend", 0);
 */
int set_quest(string pl_name, string qu_name, int no_xp) {
    int qu_level, qu_xp;
    object ob;

    // guests can't do quests.
    if( find_player(pl_name)->query_property("guest") )
        return 0;

    // Inactive quests automatically fail.
    if( !QUEST_HANDLER->query_quest_status(qu_name) )
        return 0;

    // clean out the qps cache so that we don't get invalid data.
    if( qps && qps[pl_name] )
        map_delete( qps, pl_name );

    get_data_file( pl_name );

    /* Already done the quest? */
    if( member_array( qu_name, quests ) != -1 )
        return 0;

    quests += ({ qu_name });
    times += ({ time() });

    /* Make sure the quest exists */
    qu_level = (int)QUEST_HANDLER->query_quest_level( qu_name );
    if( qu_level < 1 )
        return 0;

    qu_xp = (int)QUEST_HANDLER->query_quest_xp( qu_name );
    if( qu_xp < 1 )
        qu_xp = qu_level * 10000;

    QUEST_HANDLER->quest_completed( pl_name, qu_name, PO );
    save_data_file( pl_name );
    ob = find_player( pl_name );
    if( objectp( ob ) ) {
         if( !no_xp ) {
             ob->adjust_xp( (qu_xp*UNSHARED/100));
             /* The 1 indicates that this xp should be */
             /* shared with other team members. */
             ob->adjust_xp( qu_xp*SHARED/100, 1 );
       }
       call_out("save_them", 1, ob );
       ob->set_title( "quest",
               (string)QUEST_HANDLER->query_quest_title( qu_name ) );
    }

    return 1;

} /* set_quest() */

/**
 * This method removes a quest from the players list of completed quests.
 * @param pl_name the player name
 * @param qu_name the quest name
 * @return 0 if they have not done the quest, 1 if they habe
 * @see /handlers/quest_handler.c
 */
int unset_quest( string pl_name, string qu_name ) {
    int qu_level, i;

    get_data_file( pl_name );

    /* haven't done the quest? */
    if( ( i = member_array( qu_name, quests ) ) == -1 )
        return 0;

    /* make sure the quest exists */
    qu_level = (int)QUEST_HANDLER->query_quest_level( qu_name );
    if( qu_level < 1 )
        return 0;

    quests -= ({ qu_name });
    times -= ({ times[i] });

    save_data_file( pl_name );
    return 1;

} /* unset_quest() */

/**
 * This method causes the player to be saved.
 * @param thing the player to save
 */
void save_them( object thing ) {
    if( thing )
        thing->save();
} /* save_them() */

/**
 * This method  sets the information related to the players quest.
 * This information is used for quests which have several parts to them
 * and information needs to be stored about the player as they attempt
 * to complete it.
 * @param pl_name the name of the player
 * @param qu_info the quest name
 * @param details the information associated with the quest.
 */
void set_player_quest_info( string pl_name, string qu_info, mixed *details ) {
    get_data_file( pl_name );
    if( !player_quest_info )
        player_quest_info = ([ ]);
    player_quest_info[qu_info] = details;
    save_data_file(pl_name);
} /* set_player_quest_info() */

/**
 * This method returns all the quest information for a player.
 * This information is used for quests which have several parts to them
 * and information needs to be stored about the player as they attempt
 * to complete it.  The keys of the mapping are the quest names and the
 * values are the information associated with the quest.
 * @param pl_name the name of the player
 * @return the mapping containing all the quest info
 */
mapping query_all_player_quest_info( string pl_name ) {
    get_data_file( pl_name );
    if( !player_quest_info )
        return 0;
    return copy(player_quest_info);
} /* query_all_player_quest_info() */

/**
 * This method returns the quest info for a specific quest.
 * This information is used for quests which have several parts to them
 * and information needs to be stored about the player as they attempt
 * to complete it.
 * @param pl_name the player name
 * @param qu_info the quest name
 * @return the information associated with the quest
 */
mixed *query_player_quest_info( string pl_name, string qu_info ) {
    get_data_file( pl_name );
    if( !player_quest_info )
        return 0;
    player_quest_info = player_quest_info + ([ ]);
    return player_quest_info[qu_info];
} /* query_player_quest_info() */

/**
 * This method returns the time at which a quest is completed.
 * @param name the name of the player to get the time for
 * @param qu_name the name of the quest
 * @return the time at which it is completed
 */
int query_quest_time( string name, string qu_name ) {
    int time;

    if( !get_data_file(name) )
        return 0;

    time = member_array( qu_name, quests );
    if( time < 0 )
        return 0;

    return times[time];

} /* query_quest_time() */

/**
 * This method returns the story associated with the player.   This is
 * created from all the information about the quests they have done
 * joined together into a neato story.
 * @param name the player name
 * @return the story of the player
 * @see /handlers/quest_handler->query_quest_story()
 */
string query_story( string name ) {
    string story, quest;

    if( !get_data_file(name) )
        return "You can find nothing in the library on " + CAP(name) + "\n";

    if( text_file != "" )
        return unguarded( (: read_file, text_file :) );

    if( !sizeof(quests) )
        return CAP( player_name )+" has lead a most unadventureous life.\n";

    story = "";

    foreach( quest in quests )
        story += QUEST_HANDLER->query_quest_story( quest )+",\n";

    return story;

} /* query_story() */

/**
 * This method tells us if the player has completed the quest.
 * @param player the name of the player
 * @param quest the quest name
 * @return 1 if the quest has been done, 0 if it has not
 */
int query_quest_done( string player, string quest ) {
    get_data_file(player);
    return member_array( quest, quests ) != -1;
} /* query_quest_done() */

/**
 * This method returns the current number of quest points gathered
 * by the player.
 * @param name the player
 * @return the current number of quest pointds
 * @see /handlers/query_handler->query_quest_level()
 */
int query_quest_points( string name ) {
    int points;
    string word;

    // qps is used to cache the count of quest points since it's expensive and
    // queried a lot.
    // the reason for storing points+1 is so that someone with 0 points still
    // comes up true under the test if(qps[name])
    if( !qps )
        qps = ([ ]);

    if( qps[name] )
        return qps[name]-1;

    get_data_file( name );
    if( !quests || !sizeof( quests ) )
        points = 0;
    else {
        foreach( word in quests )
            points += (int)QUEST_HANDLER->query_quest_level( word );
    }

     qps[name] = points+1;

     return points;

} /* query_quest_points() */

/**
 * This method is called when a player refreshes totally or gets deleted.
 * @param name the player name
 * @return 0 if they do not exists, 1 if they do
 */
int restart( string name ) {
    if( TP != this_player(1) && PO != find_object("/handlers/refresh") )
        return 0;

    // clean out the qps cache so that we don't get invalid data.
    if( !qps )
        qps = ([ ]);

    if( !undefinedp( qps[name] ) )
        map_delete( qps, name );

    player_name = 0;
    unguarded( (: rm, RESTORE_PATH+name[0..0]+"/"+name+".o" :) );
    return 1;

} /* restart() */