/**
* This is the tattooist NPC inherit for tattoo parlours,
* which should be inherited into tattooist NPCs.
* You should also use set_home_location() on them, and set it to
* their tattoo parlour room; this will make sure they refuse to
* tattoo anything when not actually in their parlour, and they will
* try to return to their home location when driven out of there.
* @author Shiannar, 15/10/01, inheritized by Sandoz, 2002.
* @see /std/shops/tattoo_shop
* @see /std/effects/other/tattoo
*/
#define TATTOO EFFECTS_DIR "/other/tattoo"
inherit NPC_OBJ;
int busy;
/** @ignore yes */
int query_busy() { return busy; }
/** @ignore yes */
void set_busy( int i ) {
set_chats_off( i );
busy = i;
} /* set_busy() */
/**
* This method does some expansion on the bodypart string.
* @param bodypart the bodypart to expand
* @param expand the string to expand with, ie. a player's poss_short()
*/
string expand_tattooable( string bodypart, string expand ) {
return TATTOO->expand_tattooable( bodypart, expand );
} /* expand_tattooable() */
/**
* This method checks for the presence of the player, etc.
* Feel free to overwrite this, but do try to keep all the
* checks intact.
* @param who the person getting a tattoo
* @return 1 if the person is here an all is fine, 0 if not
*/
int check_person( object who ) {
if( !who || ENV(who) != ENV(TO) ) {
do_command("'Odd, where'd they go?");
set_busy( 0 );
return 0;
}
if( TO->is_fighting(who) ) {
do_command("'I certainly won't serve someone like you!");
set_busy( 0 );
return 0;
}
if( base_name(ENV(TO)) != query_home_location() ) {
do_command("'This isn't my tattooing shop! I can't work here!");
set_busy( 0 );
return 0;
}
return 1;
} /* check_person() */
void create() {
::create();
add_adjective("tattooist artist");
add_alias("tattooist");
} /* create() */
/**
* This method starts the actual tattooing process.
* Feel free to overwrite it in your NPC for custom messages, etc.,
* and also use check_person() in each stage.
* @param who the person getting a tattoo
* @param tattoo the thing to tattoo onto them
* @param the bodypart to tattoo onto
* @return 1 upon success, 0 upon failure
*/
int do_tattoo( object who, string tattoo, string bodypart ) {
if( !check_person(who) )
return 0;
do_command("'Well now, "+who->query_cap_name()+", "+tattoo+"?");
tell_room( ENV(who), the_short()+" takes "+who->poss_short()+" money "
"and hides it somewhere.\n");
init_command(":prepares a couple of needles and some ink.", 4 );
set_busy( 1 );
call_out("tattoo_2", 10, who, tattoo, bodypart );
return 1;
} /* do_tattoo() */
/** This method is used by the default do_tattoo(). */
void tattoo_2( object who, string tattoo, string bodypart ) {
if( !check_person(who) )
return;
do_command(":mixes a couple of ink colours together.");
init_command("'Now, this may hurt a bit. Kind of like a thousand "
"tiny fish-hooks lancing through your skin.", 4 );
init_command("grin wryly", 5 );
call_out("tattoo_3", 10, who, tattoo, bodypart );
} /* tattoo_2() */
/** This method is used by the default do_tattoo(). */
void tattoo_3( object who, string tattoo, string bodypart ) {
if( !check_person(who) )
return;
tell_object( who, the_short()+" painfully lances your skin multiple "
"times with "+HIS+" needles.\n");
tell_room( ENV(who), the_short()+" tattoos a picture into "+
who->poss_short()+" skin.\n", who );
call_out("finish_tattoo", 10, who, tattoo, bodypart );
} /* tattoo_3() */
/**
* This method finishes the tattooing process.
* Feel free to overwrite this function for custom messages,
* but do try to keep all the checks intact.
* @param who the person getting a tattoo
* @param tattoo the thing to be tattooed
* @param bodypart the bodypart to tattoo onto
*/
void finish_tattoo( object who, string tattoo, string bodypart ) {
if( !check_person(who) )
return;
tell_object( who, the_short()+" carefully draws "+tattoo+" "+
expand_tattooable( bodypart, "your")+", paying extra attention to "
"detail.\n");
tell_room( ENV(who), the_short()+" draws a tattoo on "+
who->poss_short()+" skin.\n", who );
who->add_effect( TATTOO, ({ bodypart, tattoo }) );
do_command("'There, all done. That wasn't too painful, was it?");
set_busy(0);
} /* finish_tattoo() */
/**
* This method starts the actual tattoo removal process.
* Feel free to overwrite it in your NPC for custom messages, etc.,
* and also use check_person() in each stage.
* @param who the person removing a tattoo
* @param the bodypart to remove a tattoo from
* @return 1 upon success, 0 upon failure
*/
int do_remove( object who, string bodypart ) {
if( !check_person(who) )
return 0;
do_command("'Well now, "+who->query_cap_name()+", you want the tattoos "+
expand_tattooable( bodypart, "your")+" removed?");
tell_room( ENV(who), the_short()+" takes "+who->poss_short()+" money "
"and hides it somewhere.\n");
init_command("'I'll see what I can do.", 2 );
set_busy( 1 );
call_out("remove_2", 10, who, bodypart );
return 1;
} /* do_remove() */
/** This method is used by the default do_remove(). */
void remove_2( object who, string bodypart ) {
if( !check_person(who) )
return;
do_command(":busies "+HIM+"self with "+HIS+" tattooing supplies.");
init_command("'Now, this may hurt. A lot.", 4 );
call_out("finish_remove", 10, who, bodypart );
} /* remove_2() */
/**
* This method finishes the removal of a tattoo.
* Feel free to overwrite this function for custom messages,
* but do try to keep all the checks intact.
* @param who the person removing a tattoo
* @param bodypart the bodypart to remove tattoos from
*/
void finish_remove( object who, string bodypart ) {
int *effs;
mapping args;
if( !check_person(who) )
return;
if( !sizeof( effs = who->effects_matching("body.tattoo") ) ) {
do_command("'Hrmm. It would appear you're not tattooed.");
return;
}
args = who->arg_of( effs[0] );
map_delete( args, bodypart );
if( !sizeof( args ) )
who->delete_effect( effs[0] );
else
who->set_arg_of( effs[0], args );
tell_object( who, the_short()+" punctures your skin multiple times "
"with "+HIS+" needles, then softly chants soft magic words to remove "
"the ink.\n"+the_short()+" then runs "+HIS+" hands over your skin, "
"leaving behind them an un-blemished surface.\n");
tell_room( ENV(who), the_short()+" somehow removes the tattoos "+
expand_tattooable( bodypart, who->poss_short() )+".\n", who );
set_busy(0);
} /* finish_remove() */
/** @ignore yes */
mixed stats() { return ::stats() + ({ ({"busy", query_busy() }) }); }