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/
/**
 * This is the training hall inherit.
 * @author Shaydz
 * @changed Moved some of the code to the skill handler.
 * - Sandoz, June 2003.
 */

#include <skills.h>

private string teaching_skill;

/** @ignore yes */
void create() {
    TO->add_help_file("training_hall");
} /* create() */

/** @ignore yes */
int do_advance_internal( string skill, int to, int by ) {
    string *bits, skill_name, outer_name;
    int lvl, max_lvl, tmp, total_xp, i;

    bits = explode( implode( explode( skill, " " ), "."), ".");

    if( strlen(bits[0]) == 2 ) {
        if( bits[0][0..1] != teaching_skill[0..1] ) {
            add_failed_mess("You cannot advance "+skill+" here.\n");
            return 0;
        }
    } else {
        if( bits[0] != teaching_skill ) {
            add_failed_mess("You cannot advance "+skill+" here.\n");
            return 0;
        }
    }

    if( !skill_name = SKILL_H->query_skill(bits) ) {
        add_failed_mess("The skill "+skill+" does not exist.\n");
        return 0;
    }

    if( !SKILL_H->query_allowed_to_teach(skill_name) ) {
        add_failed_mess("You cannot learn "+skill_name+" in here.\n");
        return 0;
    }

    lvl = TP->query_skill( skill_name );

    if( !by && to )
        by = to - lvl;

    if( by <= 0 ) {
        if( !by )
            add_failed_mess("You are already at level "+lvl+" in "+
                skill_name+".\n");
        else
            add_failed_mess("You cannot regress below your current "
                "skill level.\n");
        return 0;
    }

    if( SKILL_H->query_only_leaf(skill_name) ) {
        if( sizeof( SKILL_H->query_immediate_children(skill_name) ) ) {
            add_failed_mess("You can only advance the outer skills "
                "(eg: general.riding.horse), not the internal skills "
                "(eg: general.riding, or general).\n");
            return 0;
        }
    } else {
        bits = explode( skill_name, ".");

        if( sizeof( bits ) > 1 ) {
            outer_name = implode( bits[ 0 .. sizeof( bits ) - 2 ], "." );
            if( ( sizeof( bits ) - 1 ) * 5 > TP->query_skill( outer_name ) ) {
                 add_failed_mess("You are not at a high enough level in "+
                     outer_name+" to advance "+skill_name+" yet.\n");
                 return 0;
            }
        }
    }

    max_lvl = STD_GUILD_OBJ->query_skill_max_level( skill_name,TP );
    
    if( lvl >= max_lvl ) {
        add_failed_mess("You cannot advance any further in "+
            skill_name+" here.\n");
        return 0;
    }

    for( i = 0; i < by; i++ ) {
        tmp = SKILL_H->query_skill_cost( TP, skill_name, i );

        if( TP->query_xp() < tmp + total_xp ) {
            if( !i ) {
                add_failed_mess("Your lack of experience prevents you from "
                    "improving "+skill_name+".\n");
                return 0;
            } else {
                tell_object( TP, "Your lack of experience prevents you from "
                    "taking all the advancement you requested in "+
                    skill_name+".  You are only trained up to level "+
                    ( i + lvl )+".\n");
            }
            break;
        }

        if( ( lvl + i ) >= max_lvl ) {
            tell_object( TP, "This training hall hasn't the resources to "
                "train you as far as you requested in "+skill_name+".  You "
                "are trained to level "+max_lvl+" instead.\n");
            break;
        }

        total_xp += tmp;
    }

    if( !total_xp ) {
        add_failed_mess("Oh dear, something has gone wrong.\n");
        return 0;
    }

    TP->adjust_xp( -total_xp );
    TP->add_skill_level( skill_name, i, total_xp );

    event( TO, "guild_advance", bits, lvl, lvl+i );

    tell_object( TP, "You advance your skill in "+skill_name+" from level "+
        lvl+" to "+( lvl + i )+" for "+total_xp+" xp.\n");
    tell_room( TO, TP->the_short()+" $V$0=advances,advance$V$ $V$0="+
        TP->HIS+",their$V$ skills.\n", TP );
    
    return 1;

} /* do_advance_internal() */

/** @ignore yes */
int do_advance( string skill ) {
    return do_advance_internal( skill, 0, 1 );
} /* do_advance() */

/** @ignore yes */
int do_advance_by( string skill, int num ) {
    return do_advance_internal( skill, 0, num );
} /* do_advance_by() */

/** @ignore yes */
int do_advance_to( string skill, int num ) {
    return do_advance_internal( skill, num, 0 );
} /* do_advance_to() */

/** @ignore yes */
private string rec_cost( mixed arr, string path, int depth, int only_leaf,
                         int brief ) {
    int i, depth_gap, ndots, o_l, tmp, lvl, max_lvl;
    string str, lpath;

    depth_gap = ( depth - 1 ) * 2;
    ndots = 19 - depth_gap;

    str = "";

    for( i = 0; i < sizeof(arr); i += SKILL_ARR_SIZE ) {
        lpath = path + arr[i];
        lvl = TP->query_skill(lpath);
        max_lvl = STD_GUILD_OBJ->query_skill_max_level( lpath, TP );
        o_l = only_leaf;

        if( depth == 1 )
            o_l = SKILL_H->query_only_leaf( lpath );

        if( lvl >= max_lvl ) {
            if( !brief ) {
                str += sprintf("%*'| 's%-*'.'s%4d/%3d  mastered\n", depth_gap,
                    "", ndots, arr[ i ], lvl, max_lvl );
            }
        } else {
            if( !o_l || !sizeof( arr[ i + SKILL_BIT] ) ) {
                if( ( o_l && sizeof( arr[ i + SKILL_BIT] ) ) ||
                    !SKILL_H->query_allowed_to_teach(lpath) ) {
                    str += sprintf("%*'| 's%-*'.'s\n", depth_gap,
                        "", ndots+18, arr[ i ] );
                } else {
                    tmp = SKILL_H->query_skill_cost( TP, lpath, 0 );
                    str += sprintf("%*'| 's%-*'.'s%4d/%3d %6d xp\n", depth_gap,
                        "", ndots, arr[ i ], lvl, max_lvl, tmp );
                }
            } else if( o_l ) {
                str += sprintf("%*'| 's%-*'.'s\n", depth_gap,
                    "", ndots+18, arr[ i ] );
            }
        }

        if( lvl >= depth * 5 || o_l ) {
            reset_eval_cost();
            str += rec_cost( arr[ i + SKILL_BIT ], lpath +".", depth + 1,
                o_l, brief );
        }
    }

    return str;

} /* rec_cost() */

/** @ignore yes */
int do_cost_internal( string skill, int to, int by ) {
    string *bits, skill_name, outer_name;
    int lvl, max_lvl, i, tmp;

    bits = explode( implode( explode( skill, " "), "."), ".");

    if( strlen(bits[0]) == 2 ){
        if( bits[0][0..1] != teaching_skill[0..1] ) {
            add_failed_mess("You cannot advance "+skill+" here, so we can't "
                "tell you how much it would cost.\n");
            return 0;
        }
    } else {
        if( bits[0] != teaching_skill ) {
            add_failed_mess("You cannot advance "+skill+" here.\n");
            return 0;
        }
    }

    if( !skill_name = SKILL_H->query_skill( bits ) ) {
        add_failed_mess("There is no such skill as "+skill+".\n");
        return 0;
    }

    if( !SKILL_H->query_allowed_to_teach(skill_name) ) {
        add_failed_mess("You cannot learn "+skill_name+" in here.\n");
        return 0;
    }

    lvl = TP->query_skill( skill_name );

    if( !by && to )
        by = to - lvl;

    if( !by ) {
        add_failed_mess("It won't cost you anything to stay at the same "
            "level.\n");
        return 0;
    }

    if( by < 0 ) {
        add_failed_mess("We don't give refund xp for regressing skills.\n");
        return 0;
    }

    bits = explode( skill_name, ".");

    if( sizeof( bits ) > 1 ) {
        if( SKILL_H->query_only_leaf(skill_name) ) {
            if( sizeof( SKILL_H->query_immediate_children(skill_name) ) ) {
                add_failed_mess("You can only advance the outer skills "
                    "(eg: general.riding.horse), not the internal skills "
                    "(eg: general.riding, or general).\n");
                return 0;
            }
        } else {
            outer_name = implode( bits[ 0 .. sizeof( bits ) - 2 ], ".");
            if( ( sizeof(bits) - 1 ) * 5 > TP->query_skill( outer_name ) ) {
                add_failed_mess("You are not at a high enough level in "+
                    outer_name+" to advance "+skill_name+" yet.\n");
                return 0;
            }
        }
    }

    max_lvl = STD_GUILD_OBJ->query_skill_max_level( skill_name, TP );
   
    if( lvl >= max_lvl ) {
        add_failed_mess("Sorry, our teachers are not capable of instructing "
            "you above level "+max_lvl+" in "+skill_name+".\n");
        return 0;
    }

    for( i = 0;i < by; i++ ) {
        if( ( lvl + i ) >= max_lvl ) {
            tell_object( TP, "Sorry, our teachers are only able to instruct "
                "you up to level "+max_lvl+" in "+skill_name+".\n");
            break;
        }

        tmp += SKILL_H->query_skill_cost( TP, skill_name, i );

    }

    printf("It would cost you %d xp to raise %s from level %d to %d.\n",
        tmp, skill_name, lvl, ( lvl + i ) );

    return 1;

} /* do_cost_internal() */

/** @ignore yes */
int do_cost( string skill ) {
    string *bits, list;
    mixed arr;
    int i;

    bits = explode( implode( explode( skill, " "), "."), ".");
   
    if( strlen(bits[0]) == 2 ) {
        if( bits[0][0..1] != teaching_skill[0..1] ) {
            add_failed_mess("You cannot advance "+skill+" here.\n");
            return 0;
        }
    } else {
        if( bits[0] != teaching_skill ) {
            add_failed_mess("You cannot advance "+skill+" here.\n");
            return 0;
        }

    }

    arr = SKILL_H->query_skills();

    if( !arr ) {
        add_failed_mess("Oops, something seems to have broken.\n");
        return 0;
    }

    i = member_array( skill, arr );
   
    if( i != -1 ) {
        list = sprintf( "%-*'='s\n", TP->query_cols() - 1,
            "======SKILLS=======Cur/Max==For Next");
        list += sprintf("%#*-s\n", TP->query_cols(),
            rec_cost( arr[ i + 3 ], skill+".", 2, 0, 0 ) );
        list += sprintf("%*'='|s\n", TP->query_cols() - 1,
            "> You have "+TP->query_xp()+" points to spend. <");
        TP->more_string( list, CAP( skill ), 1 );
        return 1;
    }

    return do_cost_internal( skill, 0, 1 );

} /* do_cost() */

/** @ignore yes */
int do_cost_to( string skill, int num ) {
    return do_cost_internal( skill, num, 0 );
} /* do_cost_to() */

/** @ignore yes */
int do_cost_by( string skill, int num ) {
    return do_cost_internal( skill, 0, num );
} /* do_cost_to() */

/** @ignore yes */
varargs void set_teaching_skill( string skill ) { teaching_skill = skill; }

/** @ignore yes */
string query_teaching_skill() { return teaching_skill; }

/** @ignore yes */
void init() {
    add_command("advance", "<string>", (: do_advance($4[0]) :) );
    add_command("advance", "<string> to <number>",
        (: do_advance_to( $4[0], $4[1] ) :) );
    add_command("advance", "<string> by <number>",
        (: do_advance_by( $4[0], $4[1] ) :) );
    add_command("cost", "<string>", (: do_cost($4[0]) :) );
    add_command("cost", "<string> to <number>",
        (: do_cost_to($4[0], $4[1]) :) );
    add_command("cost", "<string> by <number>",
        (: do_cost_by($4[0], $4[1]) :) );
} /* init() */