#include "define.h"
#include "struct.h"
char_data* list_followers ( char_data* );
/*
* FOLLOWER ROUTINES
*/
void degroup( char_data* ch )
{
remove_bit( &ch->status, STAT_IN_GROUP );
for( int i = 0; i < ch->followers; i++ )
degroup( ch->followers[i] );
}
void do_follow( char_data* ch, char* argument )
{
char_data* victim;
if( ( victim = one_character( ch, argument, "follow", ch->array ) ) == NULL )
return;
if( is_set( &ch->status, STAT_PET ) ) {
interpret( ch, "sulk" );
interpret( ch, "shake" );
return;
}
if( victim == ch ) {
if( ch->leader == NULL ) {
send( ch, "You already follow yourself.\r\n" );
return;
}
stop_follower( ch );
return;
}
if( victim->species != NULL ) {
send( ch, "You can only follow players.\r\n" );
return;
}
if( !associate( ch, victim ) )
return;
if( ch->leader != NULL )
stop_follower( ch );
add_follower( ch, victim );
}
void add_follower( char_data* ch, char_data* victim, bool msg )
{
char_data* leader;
if( ch->leader != NULL ) {
bug( "Add_follower: non-null leader." );
return;
}
for( leader = victim->leader; leader != NULL; leader = leader->leader )
if( leader == ch ) {
send( ch, "No loops in follow allowed.\r\n" );
return;
}
ch->leader = victim;
victim->followers += ch;
degroup( ch );
if( msg ) {
if( ch->Seen( victim ) )
send( victim, "%s now follows you.\r\n", ch );
send( ch, "You now follow %s.\r\n", victim->Seen_Name( ch ) );
send_seen( ch, "%s starts following %s.\r\n", ch, victim );
}
}
void stop_follower( char_data* ch )
{
char tmp [ TWO_LINES ];
player_data* pc;
if( ch->leader == NULL ) {
bug( "Stop_follower: null leader." );
bug( "-- Ch = %s", ch->descr->name );
return;
}
if( is_set( &ch->status, STAT_PET ) ) {
remove_bit( &ch->status, STAT_PET );
remove_bit( &ch->status, STAT_TAMED );
remove_bit( &ch->status, STAT_FAMILIAR );
pc = player( ch->leader );
if( pc->familiar == ch )
pc->familiar = NULL;
sprintf( tmp, "%s [PET] stopped following.", ch->descr->name );
player_log( pc, tmp );
}
if( ch->Seen( ch->leader ) )
send( ch->leader, "%s stops following you.\r\n", ch );
send( ch, "You stop following %s.\r\n", ch->leader );
remove_bit( &ch->status, STAT_IN_GROUP );
ch->leader->followers -= ch;
ch->leader = NULL;
}
/*
* GROUP ROUTINES
*/
void add_group( char_data* ch, char_data* victim )
{
if( victim == ch ) {
send( ch, "You add yourself to your group.\r\n" );
send_seen( ch, "%s joins %s own group.\r\n",
ch, ch->His_Her( ) );
set_bit( &ch->status, STAT_IN_GROUP );
return;
}
if( !is_set( &ch->status, STAT_IN_GROUP ) ) {
send( ch, "You need to group yourself first.\r\n" );
return;
}
send( victim, "You join %s's group.\r\n", ch );
send( ch, "%s joins your group.\r\n", victim );
send_seen( victim, "%s joins %s's group.\r\n", victim, ch );
set_bit( &victim->status, STAT_IN_GROUP );
}
void group_all( char_data* ch )
{
char_data* rch;
bool found = FALSE;
if( !is_set( &ch->status, STAT_IN_GROUP ) ) {
add_group( ch, ch );
found = TRUE;
}
for( int i = 0; i < *ch->array; i++ )
if( ( rch = character( ch->array->list[i] ) ) != NULL
&& rch->leader == ch && !is_set( &rch->status, STAT_IN_GROUP )
&& rch->Seen( ch ) ) {
add_group( ch, rch );
found = TRUE;
}
if( !found )
send( ch, "You and anyone following you are already grouped.\r\n" );
}
void display_group( char_data* ch )
{
char tmp [ TWO_LINES ];
char name [ TWO_LINES ];
char hp [ 15 ];
char move [ 15 ];
char energy [ 15 ];
char_data* gch;
char_data* leader;
char_array* array;
char_array incognito;
bool found = FALSE;
int i;
if( !is_set( &ch->status, STAT_IN_GROUP ) ) {
send( ch, "You aren't in any group.\r\n" );
return;
}
for( leader = ch; leader->leader != NULL; leader = leader->leader );
send( ch, "Leader: %s\r\n", leader );
send_underlined( ch,
" Hits Energy Moves\
Exp\r\n" );
array = followers( leader );
for( i = 0; i < *array; i++ ) {
gch = array->list[i];
if( !is_set( &gch->status, STAT_IN_GROUP ) )
continue;
if( gch != ch && gch->pcdata != NULL
&& is_set( gch->pcdata->pfile->flags, PLR_GROUP_INCOG ) ) {
incognito += gch;
continue;
}
strcpy( name, gch->Seen_Name( ch ) );
truncate( name, 17 );
sprintf( hp, "%d/%d", gch->hit, gch->max_hit );
sprintf( energy, "%d/%d", gch->mana, gch->max_mana );
sprintf( move, "%d/%d", gch->move, gch->max_move );
sprintf( tmp,
"[ %2d %3s %3s ] %-17s %9s %9s %9s %12d\r\n",
gch->shdata->level, gch->species != NULL
? "Mob" : clss_table[ gch->pcdata->clss ].abbrev,
race_table[ gch->shdata->race ].abbrev,
name, hp, energy, move,
gch->pcdata == NULL ? 0 : exp_for_level( gch )-gch->exp );
tmp[15] = toupper( tmp[15] );
send( ch, tmp );
}
delete array;
for( i = 0; i < incognito; i++ ) {
if( !found ) {
found = TRUE;
send( ch, "%46s\r\n", "-*-" );
}
send( ch, "[ Incognito ] %-29s %s\r\n",
incognito[i], condition_word( incognito[i] ) );
}
}
void do_group( char_data* ch, char* argument )
{
char_data* victim;
if( *argument == '\0' ) {
display_group( ch );
return;
}
if( ch->leader != NULL ) {
send( ch, "But you are following someone else!\r\n" );
return;
}
if( !strcasecmp( argument, "all" ) ) {
group_all( ch );
return;
}
if( ( victim = one_character( ch, argument, "group",
ch->array, (thing_array*) &ch->followers ) ) == NULL )
return;
if( victim->leader != ch && ch != victim ) {
send( ch, "%s isn't following you.\r\n", victim );
return;
}
if( is_set( &victim->status, STAT_IN_GROUP ) ) {
if( victim != ch ) {
send( ch, "You remove %s from your group.\r\n", victim );
send( victim, "%s removes you from %s group.\r\n",
ch, ch->His_Her( ) );
send( *ch->array, "%s removes %s from %s group.\r\n",
ch, victim, ch->His_Her( ) );
if( !is_set( &victim->status, STAT_PET ) )
stop_follower( victim );
}
else {
send( "You remove yourself from your group.\r\n", ch );
send_seen( ch, "%s removes %sself from %s group.\r\n",
ch, ch->Him_Her( ), ch->His_Her( ) );
}
remove_bit( &victim->status, STAT_IN_GROUP );
return;
}
add_group( ch, victim );
}
/*
* UTILITY ROUTINES
*/
void add_followers( char_data* ch, char_array& array,
content_array* where )
{
if( where != NULL && ch->array != where )
return;
array += ch;
for( int i = 0; i < ch->followers; i++ )
add_followers( ch->followers[i], array, where );
}
char_array* followers( char_data* leader, content_array* where )
{
char_array* array = new char_array;
add_followers( leader, *array, where );
return array;
}
int min_group_move( char_data* ch )
{
char_data* rch;
int move = ch->move;
for( int i = 0; i < *ch->array; i++ )
if( ( rch = character( ch->array->list[i] ) ) != NULL
&& is_same_group( ch, rch ) && rch != ch )
move = min( move, rch->move );
return move;
}
bool is_same_group( char_data* ach, char_data* bch )
{
if( ach == NULL || bch == NULL )
return FALSE;
if( ach == bch )
return TRUE;
if( !is_set( &ach->status, STAT_IN_GROUP )
|| !is_set( &bch->status, STAT_IN_GROUP ) )
return FALSE;
for( ; ach->leader != NULL; ach = ach->leader );
for( ; bch->leader != NULL; bch = bch->leader );
return( ach == bch );
}
/*
* ORDER COMMAND
*/
void do_order( char_data* ch, char* argument )
{
char arg [ MAX_INPUT_LENGTH ];
char_data* rch;
thing_array list;
room_data* room = ch->in_room;
bool found = FALSE;
if( !two_argument( argument, "to", arg ) ) {
argument = one_argument( argument, arg );
if( *argument == '\0' ) {
send( ch, "Syntax: Order <pet|all> [to] <command>\r\n" );
return;
}
}
if( strcasecmp( arg, "all" ) ) {
if( ( rch = one_character( ch, arg, "order", ch->array ) ) == NULL )
return;
if( rch == ch ) {
send( ch, "Ordering yourself makes no sense.\r\n" );
return;
}
send( ch, "You order %s to '%s'.\r\n", rch, argument );
if( rch->position > POS_SLEEPING )
send( rch, "%s orders you to '%s'.\r\n", ch, argument );
send( *ch->array, "%s orders %s to '%s'.\r\n",
ch, rch, argument );
if( !is_set( &rch->status, STAT_PET ) || rch->leader != ch ) {
send( ch, "%s ignores you.\r\n", rch );
return;
}
set_bit( &rch->status, STAT_ORDERED );
interpret( rch, argument );
remove_bit( &rch->status, STAT_ORDERED );
return;
}
send( *ch->array, "%s orders all %s followers to '%s'.\r\n",
ch, ch->His_Her( ), argument );
copy( list, *ch->array );
for( int i = 0; i < list; i++ ) {
if( ( rch = character( list[i] ) ) == NULL
|| rch->array != &room->contents
|| !is_set( &rch->status, STAT_PET )
|| rch->leader != ch )
continue;
if( !found ) {
fsend( ch, "You order all your followers to '%s'.\r\n",
argument );
found = TRUE;
}
set_bit( &rch->status, STAT_ORDERED );
interpret( rch, argument );
remove_bit( &rch->status, STAT_ORDERED );
}
if( !found )
send( ch, "You have no followers here.\r\n" );
}