inherit "/std/effect_shadow";
int turn_chance;
object my_owner;
object my_enemy;
string leave_msg;
string enter_msg;
int summoned;
int set_enemy( object enemy );
object query_owner() { return my_owner; }
object query_enemy() { return my_enemy; }
void set_leave_msg( string mess ) { leave_msg = mess; }
void set_enter_msg( string mess ) { enter_msg = mess; }
void set_summoned( int summ ) { summoned = summ; }
void init() {
player->init();
if( this_player() != my_owner )
return;
this_player()->add_command( "help", this_object(), "<direct:living:here>" );
this_player()->add_command( "order", this_object(),
"<direct:living:here> to {kill|attack} <indirect:living:here>" );
this_player()->add_command( "order", this_object(),
"<direct:living:here> to protect <indirect:living:here>" );
this_player()->add_command( "order", this_object(),
"<direct:living:here> to leave" );
}
int do_order( object *indir, string indir_match, string dir_match,
mixed *args, string pattern ) {
if( this_player() != my_owner )
return 0;
if( pattern == "<direct:living:here> to leave" ) {
my_owner->add_succeeded_mess( this_object(),
"$D smiles happily.\n", ({ }) );
tell_object( my_owner,
(string)this_object()->the_short() +
" tells you: Thank you.\n");
if ( summoned ) {
call_out( "go_away", 1 );
} else {
my_owner = 0;
call_out( "run_away", 1 );
}
} else if ( pattern == "<direct:living:here> to protect <indirect:living:here>" ) {
if ( !indir ) {
my_owner->add_failed_mess( this_object(),
"$D asks you: Who do you want me to protect?\n", ({ }) );
return 0;
}
tell_object( indir[ 0 ], (string)this_object()->the_short() +" tells you: "+
(string)my_owner->the_short()
+" has asked me to protect you.\n" );
tell_object( my_owner, (string)this_object()->the_short()
+" tells you: Fine.\n" );
this_player()->add_succeeded_mess( this_object(),
"$N $V $D to protect $I.\n ", ({ indir[ 0 ] }) );
this_object()->do_command( "protect "+
(string)indir[ 0 ]->query_name() );
} else {
if ( !indir ) {
my_owner->add_failed_mess( this_object(),
"$D asks you: Who do you want me to kill?\n", ({ }) );
return 0;
}
if ( !set_enemy( indir[ 0 ] ) ) {
my_owner->add_failed_mess( this_object(),
"$D tells you: There is no way you can force me to attack $I.\n",
({ indir[ 0 ] }));
return 0;
};
tell_object( my_enemy, (string)this_object()->the_short() +
" tells you: "+
(string)my_owner->the_short()
+" has asked me to kill you.\nPrepare to die!\n" );
tell_object( my_owner, this_object()->the_short() +
" tells you: Fine.\n" );
}
return 1;
}
int do_help( object *indir, string indir_match, string dir_match,
mixed *args, string pattern ) {
if ( this_player() != my_owner )
return 0;
this_player()->add_succeeded_mess( this_object(),
"You can \"order\" "+
this_object()->the_short()
+" to kill someone or to leave.\n ", ({ }) );
return 1;
}
int set_enemy( object enemy ) {
object *list;
int i;
my_enemy = enemy;
if( my_enemy == my_owner ) {
my_owner = 0; /******* stop attacking owners foes ******/
list = this_object()->query_attacker_list();
for( i = 0; i < sizeof(list); i++ ) {
this_object()->stop_fight( list[i] );
(list[ i ])->stop_fight( this_object() );
if ( !pk_check( list[ i ], my_enemy ) ) {
(list[ i ])->attack_ob( my_enemy );
my_enemy->attack_ob( list[ i ] );
tell_object( list[ i ], (string)this_object()->the_short()
+" tells you: I will help you fight "+
(string)my_enemy->the_short() +".\n");
}
}
} else {
if ( pk_check( my_owner, my_enemy ) ) {
if ( turn_chance )
call_out( "set_enemy", 1, my_owner );
else
call_out( "go_away", 1);
return 0;
}
}
this_object()->attack_ob( my_enemy );
call_out( "move_me", 1 );
return 1;
} /* set_enemy() */
int set_owner( object owner, int time, int turn) {
if ( !owner ) return 0;
my_owner = owner;
turn_chance = turn;
if ( summoned )
call_out( "do_leave", time ) ;
call_out( "move_me", 1 );
return 1;
} /* set_owner() */
void event_dest_me( object ob ) {
if ( ob == my_owner )
call_out( "go_away", 0 );
if ( ob == my_enemy ) {
if ( !my_owner )
call_out( "go_away", 0 );
if ( my_enemy )
tell_object( my_owner, (string)my_enemy->the_short() +" has left DiscWorld\n" );
my_enemy = 0;
call_out( "move_me",0);
}
} /* event_dest_me() */
void event_death( object ob ) {
if ( ob == my_enemy ) {
if ( !my_owner ) call_out( "go_away", 0 );
/* call_out to preven the monster from bragging
* before the death message */
call_out( "do_tell", 0, my_owner, this_object()->query_short() +" tells you: "+
my_enemy->the_short() +" has been killed!\n");
my_enemy = 0;
call_out( "move_me", 0 );
}
} /* event_death() */
void do_tell( object ob, string str ) {
tell_object( ob, str );
} /* do_tell() */
/*********************** Follow owner or enemy **********/
void move_me() {
if ( my_enemy ) {
if ( environment() == environment( my_enemy ) ) return;
player->move( environment( my_enemy ), enter_msg, leave_msg );
tell_object( my_enemy, this_object()->the_short() +" says: You cannot escape me!\n" );
return;
}
if ( my_owner ) {
if ( environment() == environment( my_owner ) ) return;
player->move( environment( my_owner ), enter_msg, leave_msg );
this_object()->do_command( "protect "+ (string)my_owner->query_name() );
this_object()->do_command( "follow "+ (string)my_owner->query_name() );
return;
}
if ( summoned )
call_out( "go_away", 0 );
else
call_out( "run_away", 1 );
} /* move_me() */
int do_leave() {
if ( my_owner ) {
tell_object( my_owner, this_object()->the_short()
+" tells you: It is time for me to leave.\n" );
say( this_object()->the_short() +" smiles happily.\n" );
}
call_out( "go_away", 2 );
return 1;
} /* do_leave() */
/**************************** ATTACK / COMBAT ***************/
int attack_by( object ob ) {
if ( summoned && !my_owner ) {
say( this_object()->the_short()
+" says: I will not fight without an owner!\n");
call_out("go_away",0);
return 1;
}
if ( interactive( my_owner ) ) {
if ( random( 100 ) < ( turn_chance / 5 ) ) {
set_enemy( my_owner );
return 1;
}
}
return player->attack_by( ob );
} /* attack_by() */
void event_exit( object ob ) {
if( ob != my_owner && ob != my_enemy ) return;
call_out( "move_me", 1 );
}
void go_away() {
write( leave_msg );
player->move( "/room/rubbish" );
} /* dest_me() */