#define HAND_STOPPED 0
#define HAND_GOING_OUT 1
#define HAND_COMING_BACK 2
inherit NPC_OBJ;
object _player;
int _heading;
int _got_it;
string owner_present();
void setup() {
set_name( "hand" );
set_short( "severed hand" );
add_adjective( ({ "severed", "grappling" }) );
set_long( (: "This is a severed hand from a corpse. It hangs ominously "
"in the air, twitching occasionally in response to some "
"arcane stimulus. $C$" + owner_present() :) );
basic_setup("strange", 1, 0 );
set_cannot_change_position( 1 );
set_default_position( ({ "hanging ominously in the air" }) );
return_to_default_position( 1 );
add_property( "floating", 1 );
_heading = HAND_STOPPED;
} /* setup() */
void init() {
::init();
if( this_player() == _player ) {
this_player()->add_command("grab",
this_object(),
"<string'item'> from [the] <string'direction'>");
}
} /* init() */
void dest_me()
{
object ob;
if( environment() )
{
if( sizeof( all_inventory( this_object() ) ) )
{
foreach( ob in all_inventory( this_object() ) )
{
ob->move( environment() );
}
}
}
::dest_me();
} /* dest_me() */
string query_msgin() {
return "$N creep$s in from $F.";
} /* query_msgin() */
string query_msgout() {
return "$N creep$s out $T.";
} /* query_msgout() */
int second_life() {
call_out( "dest_me", 2 );
return 1;
} /* second_life() */
void setup_player( object ob ) {
_player = ob;
} /* setup_player() */
object query_my_player() { return _player; }
int do_grab( object *, string, string, mixed *args ) {
/* Ok, in theory args[1] will contain the place to go to... */
tell_creator( this_player(), "Args: %O\n", args );
if( _heading != HAND_STOPPED )
{
return notify_fail( "You have already given the hand an order.\n" );
}
// dir = args[ 1 ];
// bits = ( explode( args[ 0 ], " " ) - ({ "" }) );
_heading = HAND_GOING_OUT;
call_out( "go_to_dest", 1, args[ 0 ], args[ 1 ] );
this_player()->add_succeeded_mess( this_object(),
"$N send$s $D off on an errand.\n", ({ }) );
return 1;
} /* do_grab() */
void go_to_dest( string what, string where ) {
string here, there, dest;
tell_creator( _player, "Attempting to move to destination...\n" );
here = file_name( environment() );
dest = environment()->query_destination( where );
if( !dest || !find_object( dest ) || !do_command( where ) )
{
tell_object( _player, "A sense of confusion briefly flows back "
"through your link with the hand. It appears to be "
"unable to find a way there.\n" );
tell_room( environment(), this_object()->one_short() +
" looks dazed and confused as it disintegrates.\n" );
call_out( "dest_me", 2 );
return;
}
else
{
there = file_name( find_object( dest ) );
call_out( "fetch_objects", 4, what, there, here );
}
} /* go_to_dest() */
void fetch_objects( string what, string destination, string origin )
{
// We haven't arrived to the right destination.
tell_creator( _player, "Attempting to fetch objects...\n" );
if( !environment() || file_name( environment() ) != destination )
{
tell_object( _player, "A sense of confusion briefly flows back "
"through your link with the hand. It appears to be "
"unable to find a way there.\n" );
tell_room( environment(), this_object()->one_short() +
" looks dazed and confused as it disintegrates.\n" );
call_out( "dest_me", 2 );
return;
}
// Let's try to get what we came for.
if( !do_command( "get " + what ) )
{
tell_object( _player, "A sense of confusion briefly flows back "
"through your link with the hand. " );
if( !sizeof( match_objects_for_existence( what, environment() ) ) )
{
tell_object( _player, "It appears to be unable to find what you "
"asked.\n" );
}
else
{
tell_object( _player, "It appears to be unable to lift what you "
"asked.\n" );
}
call_out( "dest_me", 2 );
return;
}
tell_creator( _player, "Hand inventory: %O\n",
all_inventory() );
call_out( "return_back", 1, what, origin );
} /* fetch_objects() */
void return_back( string what, string origin )
{
string exit, exit_to_use;
object destination;
tell_creator( _player, "Attempting to return back...\n" );
_heading = HAND_COMING_BACK;
exit_to_use = 0;
foreach( exit in environment()->query_exits() )
{
destination = find_object( environment()->query_destination( exit ) );
if( destination && file_name( destination ) == origin )
{
exit_to_use = exit;
break;
}
}
if( !exit_to_use || !do_command( exit_to_use ) )
{
tell_object( _player, "A sense of confusion briefly flows back "
"through your link with the hand. It appears to be "
"unable to find a way back.\n" );
tell_room( environment(), this_object()->one_short() +
" looks dazed and confused as it disintegrates.\n" );
call_out( "dest_me", 2 );
return;
}
call_out( "return_items", 4, what );
} /* return_back() */
void return_items( string what )
{
tell_creator( _player, "Attempting to return items...\n" );
if( _player )
{
if( environment( _player ) != environment() || !_player->query_visible( this_object() ) )
{
tell_object( _player, "A sense of sadness briefly flows back "
"through your link with the hand. It appears the hand "
"can't find you.\n" );
tell_room( environment(), this_object()->one_short() +
" looks sad and forlorn as it disintegrates.\n" );
call_out( "dest_me", 2 );
return;
}
if( do_command( "give " + what + " to " + _player->query_name() ) )
{
tell_room( environment(), this_object()->one_short() +
" disintegrates happily.\n" );
}
else
{
tell_room( environment(), this_object()->one_short() +
" looks ashamed as it disintegrates into nothingness.\n" );
}
call_out( "dest_me", 2 );
}
} /* return_items() */
string owner_present() {
if ( _player && environment() == environment( _player ) ) {
return "It looks curiously at " + _player->one_short() + ".\n";
}
else {
return "\n";
}
} /* owner_present() */
void event_exit( object ob ) {
if ( ob == _player && _heading == HAND_STOPPED ) {
tell_room( environment(), this_object()->one_short() + " looks "
"hurt as its owner abandons it. It crumbles into a sad "
"little pile of dust.\n" );
tell_object( _player, "A brief sense of rejection comes through "
"your link with the hand as you abandon it.\n");
call_out( "dest_me", 2 );
}
} /* event_exit() */