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 basic tattoo parlour inherit.
 * To use the inherit, you need to assign a tattooist NPC object to
 * the 'keeper' variable, and deal with the cloning and checking for
 * his/her existance each reset, etc.
 * @see set_tattoo_cost()
 * @see set_remove_cost()
 * @see /std/effects/other/tattoo
 * @see /std/npcs/tattooist
 * @author Shiannar, 14/10/01, inheritized by Sandoz, 2002.
 */

#define TATTOO      EFFECTS_DIR "/other/tattoo"

#define TATTOO_COST 72000  // Default cost is 12 platinum coins.
#define REMOVE_COST 144000 // Removal cost is 24 platinum coins.
#define QMS(x)      query_multiple_short( x, "poss", 1 ) // 1st person.

inherit ROOM_OBJ;

string place;
object keeper;
int tattoo_cost, remove_cost;

void create() {
    remove_cost = REMOVE_COST;
    ::create();
    add_help_file("tattoo_parlour");
} /* create() */

/**
 * This method sets the cost of a single tattoo.
 * @param cost the cost of a single tattoo
 */
void set_tattoo_cost( int cost ) { tattoo_cost = cost; }

/**
 * This method returns the cost of a tattoo in this parlour.
 * @return the cost of a tattoo in this parlour
 */
int query_tattoo_cost() { return tattoo_cost || TATTOO_COST; }

/**
 * This method sets the cost of tattoo removal in this parlour.
 * If set to 0, then no removal services are offered.
 * @param cost the tattoo removal cost, if 0, no removal is offered
 */
void set_remove_cost( int cost ) { remove_cost = cost; }

/**
 * This method returns the tattoo removal cost in this parlour.
 * @return the tattoo removal cost
 */
int query_remove_cost() { return remove_cost; }

/**
 * This method sets the monetary area of the parlour.
 * This is used to decide which currency to accept here.
 * @param str the place to set
 */
void set_place( string str ) { place = str; }

/**
 * This method returns the place name to use for currency calculations.
 * @return the monetary area this parlour is in
 */
string query_place() { return place || "default"; }

/**
 * This method returns all the tattooable bodyparts.
 * @return all the tattooable bodyparts
 */
string *query_tattooables() { return TATTOO->query_tattooables(); }

int check_keeper() {
    return ( keeper && ENV(keeper) == TO );
} /* check_keeper() */

/** @ignore yes */
int do_request( string tattoo, string bodypart ) {
    object *obs;

    if( !check_keeper() ) {
        add_succeeded_mess( ({
            "The tattoo artist is not here to serve you!\n",
            "$N look$s around and blink$s.\n"}) );
        return 1;
    }

    tell_object( TP, "You enquire about getting a tattoo.\n");
    tell_room( TO, TP->the_short()+" $V$0=enquires,enquire$V$ about getting "
        "a tattoo done.\n", TP );

    if( keeper->query_busy() ) {
        keeper->do_command("sayto "+TP->query_name()+" I'm busy right "
                "now, you can go next.");
        return notify_fail("");
    }

    if( !TATTOO->query_tattooable( bodypart ) ) {
        keeper->do_command("sayto "+TP->query_name()+" I'm sorry, but I "
            "cannot tattoo your \""+bodypart+"\".  Please read the sign "
            "for the list of available bodyparts.");
        return notify_fail("");
    }

    if( sizeof( obs = TATTOO->query_tattoo_covered( TP, bodypart ) ) ) {
        keeper->do_command("sayto "+TP->query_name()+" I'm afraid you are "
            "going to have to remove "+QMS(obs)+" before I can help you.");
        return notify_fail("");
    }

    if( lower_case(tattoo) == "tattoo") {
        keeper->do_command("sayto "+TP->query_name()+" I know you want a "
            "tattoo, but I need to know more details.");
        return notify_fail("");
    }

    if( TP->query_value_in( query_place() ) < tattoo_cost ) {
        keeper->do_command("sayto "+TP->query_name()+" I'm sorry, "+
            TP->short()+", but you need "+MONEY_H->money_value_string(
            query_tattoo_cost(), query_place() )+" or the same in change to "
            "get a tattoo.");
        return notify_fail("");
    }

    TP->pay_money( MONEY_H->create_money_array( query_tattoo_cost(),
        query_place() ), query_place() );

    add_succeeded_mess("");

    return keeper->do_tattoo( TP, tattoo, bodypart );

} /* do_request() */

/** @ignore yes */
int do_remove( string bodypart ) {
    object *obs;
    int *effs;

    if( !check_keeper() ) {
        add_succeeded_mess( ({
            "The tattoo artist is not here to serve you!\n",
            "$N look$s around and blink$s.\n"}) );
        return 1;
    }

    tell_object( TP, "You enquire about getting a tattoo removed.\n");
    tell_room( TO, TP->the_short()+" $V$0=enquires,enquire$V$ about getting "
        "a tattoo removed.\n", TP );

    if( keeper->query_busy() ) {
        keeper->do_command("sayto "+TP->query_name()+" I'm busy right now, "
                "you can go next.");
        return notify_fail("");
    }

    if( !TATTOO->query_tattooable( bodypart ) ) {
        keeper->do_command("peer "+TP->query_name()+" carefully");
        keeper->do_command("sayto "+TP->query_name()+" I'm sorry, but \""+
                bodypart+"\" is a bodypart I have never heard of before.");
        return notify_fail("");
    }

    if( sizeof( obs = TATTOO->query_tattoo_covered( TP, bodypart ) ) ) {
        keeper->do_command("sayto "+TP->query_name()+" I'm afraid you are "
            "going to have to remove "+QMS(obs)+" before I can help you.");
        return notify_fail("");
    }

    if( !sizeof( effs = TP->effects_matching("body.tattoo") ) ) {
        keeper->do_command("'Hrmm.  It would appear you're not tattooed.");
        return notify_fail("");
    }

    if( undefinedp( TP->arg_of( effs[0] )[bodypart] ) ) {
        keeper->do_command("'Hrmm.  It would appear you have no tattoos "+
            TATTOO->expand_tattooable( bodypart, "your")+".");
        return notify_fail("");
    }

    if( TP->query_value_in( query_place() ) < query_remove_cost() ) {
        keeper->do_command("sayto "+TP->query_name()+" I'm sorry, "+
            TP->short()+", but you need "+MONEY_H->money_value_string(
            query_remove_cost(), query_place() )+" or the same in change to "
            "get a tattoo removed.");
        return notify_fail("");
    }

    TP->pay_money( MONEY_H->create_money_array( query_remove_cost(),
        query_place() ), query_place() );

    add_succeeded_mess("");

    return keeper->do_remove( TP, bodypart );

} /* do_remove() */

/** @ignore yes */
void init() {
    ::init();
    add_command("request", "<string'tattoo'> on [my] <string'bodypart'>",
        (: do_request( $4[0], $4[1] ) :) );
    if( remove_cost )
        add_command("remove", "tattoos {on|from} [my] <string'bodypart'>",
            (: do_remove( $4[1] ) :) );
} /* init() */

/** @ignore yes */
mixed stats() {
    return ::stats() + ({
        ({"tattoo cost", tattoo_cost }),
        ({"removal cost", remove_cost }),
        ({"no removal", !remove_cost }),
        ({"place", query_place() }),
        ({"keeper", keeper }),
    });
} /* stats() */